-diff -Nauprw linux-2.6.20/arch/arm/common/rtctime.c ../new/linux-2.6.20/arch/arm/common/rtctime.c
---- linux-2.6.20/arch/arm/common/rtctime.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/common/rtctime.c 2007-11-21 11:51:41.000000000 +0530
-@@ -201,13 +201,13 @@ static int rtc_ioctl(struct inode *inode
- }
- alrm.enabled = 0;
- alrm.pending = 0;
-- alrm.time.tm_mday = -1;
-+/* alrm.time.tm_mday = -1;
- alrm.time.tm_mon = -1;
- alrm.time.tm_year = -1;
- alrm.time.tm_wday = -1;
- alrm.time.tm_yday = -1;
- alrm.time.tm_isdst = -1;
-- ret = rtc_arm_set_alarm(ops, &alrm);
-+*/ ret = rtc_arm_set_alarm(ops, &alrm);
- break;
+---
+ .gitignore | 47
+ Documentation/DocBook/Makefile | 3
+ Documentation/DocBook/kgdb.tmpl | 234
+ Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt | 111
+ Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt | 106
+ Documentation/arm/STM-Nomadik/debug_strategy.txt | 66
+ Documentation/arm/STM-Nomadik/dma_user_guide.txt | 420
+ Documentation/arm/STM-Nomadik/faqs.txt | 53
+ Documentation/arm/STM-Nomadik/gpio_user_guide.txt | 140
+ Documentation/arm/STM-Nomadik/irq_usrguide.txt | 171
+ Documentation/arm/STM-Nomadik/power_management.txt | 122
+ MAINTAINERS | 9
+ Makefile | 18
+ arch/arm/Kconfig | 25
+ arch/arm/Makefile | 34
+ arch/arm/common/rtctime.c | 4
+ arch/arm/configs/ndk10_defconfig | 1205 +
+ arch/arm/configs/ndk15_defconfig | 1221 +
+ arch/arm/configs/ndk15b06_defconfig | 1221 +
+ arch/arm/configs/nhk15_defconfig | 1458 +
+ arch/arm/kernel/Makefile | 1
+ arch/arm/kernel/armksyms.c | 14
+ arch/arm/kernel/dma.c | 1
+ arch/arm/kernel/entry-armv.S | 2
+ arch/arm/kernel/irq.c | 12
+ arch/arm/kernel/kgdb-jmp.S | 30
+ arch/arm/kernel/kgdb.c | 208
+ arch/arm/kernel/setup.c | 5
+ arch/arm/kernel/traps.c | 11
+ arch/arm/lib/Makefile | 2
+ arch/arm/lib/gcclib.h | 25
+ arch/arm/lib/longlong.h | 184
+ arch/arm/lib/udivdi3.c | 246
+ arch/arm/mach-nomadik/Kconfig-nomadik | 267
+ arch/arm/mach-nomadik/Makefile | 166
+ arch/arm/mach-nomadik/Makefile.boot | 4
+ arch/arm/mach-nomadik/clock.c | 127
+ arch/arm/mach-nomadik/clock.h | 25
+ arch/arm/mach-nomadik/cpu.c | 293
+ arch/arm/mach-nomadik/create_kconfig.pl | 55
+ arch/arm/mach-nomadik/deep_sleep.S | 655
+ arch/arm/mach-nomadik/dfs.S | 355
+ arch/arm/mach-nomadik/dma.c | 1337 +
+ arch/arm/mach-nomadik/fsmc.c | 113
+ arch/arm/mach-nomadik/gpio.c | 916 +
+ arch/arm/mach-nomadik/irq.c | 231
+ arch/arm/mach-nomadik/l2cc.c | 152
+ arch/arm/mach-nomadik/msp.c | 2062 ++
+ arch/arm/mach-nomadik/msp.h | 383
+ arch/arm/mach-nomadik/mtu.c | 589
+ arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig | 28
+ arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig | 35
+ arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig | 35
+ arch/arm/mach-nomadik/ndk10_devices.c | 1225 +
+ arch/arm/mach-nomadik/ndk15_devices.c | 1001 +
+ arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig | 37
+ arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig | 37
+ arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig | 42
+ arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig | 42
+ arch/arm/mach-nomadik/ndk15c02_devices.c | 1023 +
+ arch/arm/mach-nomadik/nhk15_Kconfig | 36
+ arch/arm/mach-nomadik/nhk15_devices.c | 1009 +
+ arch/arm/mach-nomadik/normal.S | 199
+ arch/arm/mach-nomadik/pm.c | 79
+ arch/arm/mach-nomadik/power.c | 1316 +
+ arch/arm/mach-nomadik/rtc.c | 327
+ arch/arm/mach-nomadik/sleep.c | 280
+ arch/arm/mach-nomadik/slow.S | 199
+ arch/arm/mach-nomadik/soft_sleep.S | 206
+ arch/arm/mach-nomadik/ssp.c | 930 +
+ arch/arm/mach-nomadik/stn8810_devices.c | 1071 +
+ arch/arm/mach-nomadik/stn8815_devices.c | 1971 ++
+ arch/arm/mach-nomadik/timer.c | 366
+ arch/arm/mm/Kconfig | 23
+ arch/arm/mm/extable.c | 7
+ arch/arm/mm/init.c | 1
+ arch/arm/mm/proc-arm926.S | 30
+ arch/arm/oprofile/common.c | 3
+ drivers/Makefile | 2
+ drivers/char/keyboard.c | 1
+ drivers/cpufreq/Kconfig | 4
+ drivers/hwmon/Kconfig | 13
+ drivers/hwmon/Makefile | 1
+ drivers/hwmon/lis3lv02dl.c | 489
+ drivers/i2c/Kconfig | 1
+ drivers/i2c/Makefile | 3
+ drivers/i2c/busses/Kconfig | 10
+ drivers/i2c/busses/Makefile | 22
+ drivers/i2c/busses/i2c-nomadik.c | 1250 +
+ drivers/i2c/busses/i2c-nomadik.h | 93
+ drivers/i2c/busses/i2c-stn8810.c | 1723 ++
+ drivers/i2c/busses/i2c-stn8815.c | 1817 ++
+ drivers/i2c/chips/Kconfig | 9
+ drivers/i2c/chips/Makefile | 6
+ drivers/i2c/chips/epio-nomadik.c | 195
+ drivers/input/input.c | 13
+ drivers/input/keyboard/Kconfig | 13
+ drivers/input/keyboard/Makefile | 7
+ drivers/input/keyboard/kpd-nomadik.c | 359
+ drivers/input/touchscreen/Kconfig | 20
+ drivers/input/touchscreen/Makefile | 8
+ drivers/input/touchscreen/touchp-nomadik.c | 755 +
+ drivers/input/touchscreen/touchp2003-nomadik.c | 566
+ drivers/media/Kconfig | 2
+ drivers/media/Makefile | 4
+ drivers/media/nomadik_mm/Kconfig | 23
+ drivers/media/nomadik_mm/Makefile | 8
+ drivers/media/nomadik_mm/hcl/hloader/hloader.c | 3632 ++++
+ drivers/media/nomadik_mm/hcl/hloader/hloader.h | 170
+ drivers/media/nomadik_mm/hcl/hloader/hloader_p.h | 451
+ drivers/media/nomadik_mm/hcl/include/debug.h | 316
+ drivers/media/nomadik_mm/hcl/include/hcl_defs.h | 290
+ drivers/media/nomadik_mm/hcl/include/hloader.h | 170
+ drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h | 1761 ++
+ drivers/media/nomadik_mm/hcl/include/platform_os.h | 72
+ drivers/media/nomadik_mm/hcl/include/sva.h | 2148 ++
+ drivers/media/nomadik_mm/hcl/saa/audio_services.c | 142
+ drivers/media/nomadik_mm/hcl/saa/audio_services.h | 39
+ drivers/media/nomadik_mm/hcl/saa/ha_api_params.h | 1064 +
+ drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h | 204
+ drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h | 686
+ drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h | 122
+ drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h | 1342 +
+ drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h | 163
+ drivers/media/nomadik_mm/hcl/saa/hti.c | 271
+ drivers/media/nomadik_mm/hcl/saa/hti.h | 159
+ drivers/media/nomadik_mm/hcl/saa/hti_protocol.h | 134
+ drivers/media/nomadik_mm/hcl/saa/saa.c | 2538 +++
+ drivers/media/nomadik_mm/hcl/saa/saa.h | 306
+ drivers/media/nomadik_mm/hcl/saa/saa_base.c | 557
+ drivers/media/nomadik_mm/hcl/saa/saa_hwp.h | 275
+ drivers/media/nomadik_mm/hcl/saa/saa_irq.c | 432
+ drivers/media/nomadik_mm/hcl/saa/saap.h | 160
+ drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c | 63
+ drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h | 46
+ drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h | 335
+ drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h | 646
+ drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c | 131
+ drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h | 61
+ drivers/media/nomadik_mm/hcl/sva/common/sva_service.h | 337
+ drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c | 486
+ drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h | 80
+ drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h | 49
+ drivers/media/nomadik_mm/hcl/sva/common/svap.h | 188
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c | 3030 ++++
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h | 110
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c | 3101 ++++
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h | 232
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h | 98
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c | 312
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h | 53
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h | 156
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c | 2126 ++
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h | 181
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c | 789 +
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h | 35
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c | 2211 ++
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h | 170
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c | 686
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h | 35
+ drivers/media/nomadik_mm/hcl/sva/decode/sva.h | 18
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h | 135
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c | 2357 +++
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h | 97
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c | 655
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h | 364
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h | 40
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c | 2044 ++
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h | 194
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c | 714
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h | 37
+ drivers/media/nomadik_mm/hcl/sva/display/sva_display.c | 5661 +++++++
+ drivers/media/nomadik_mm/hcl/sva/display/sva_display.h | 99
+ drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h | 424
+ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c | 3648 ++++
+ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h | 112
+ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h | 262
+ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c | 4739 ++++++
+ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h | 79
+ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h | 646
+ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c | 2556 +++
+ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h | 69
+ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h | 246
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h | 187
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c | 4594 ++++++
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h | 90
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h | 340
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c | 896 +
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h | 97
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h | 84
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c | 225
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h | 42
+ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c | 1907 ++
+ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h | 180
+ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h | 304
+ drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c | 3810 +++++
+ drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h | 88
+ drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h | 411
+ drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h | 87
+ drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h | 111
+ drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h | 46
+ drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h | 181
+ drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h | 97
+ drivers/media/nomadik_mm/hcl/sva/include/sva_display.h | 99
+ drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h | 90
+ drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h | 97
+ drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h | 335
+ drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h | 180
+ drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h | 89
+ drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h | 290
+ drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h | 60
+ drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h | 42
+ drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h | 163
+ drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h | 62
+ drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h | 71
+ drivers/media/nomadik_mm/hcl/sva/include/sva_service.h | 337
+ drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h | 89
+ drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h | 111
+ drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h | 96
+ drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h | 403
+ drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h | 80
+ drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h | 89
+ drivers/media/nomadik_mm/hcl/sva/include/svap.h | 193
+ drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h | 1725 ++
+ drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h | 41
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c | 541
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h | 87
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h | 73
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c | 1212 +
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h | 111
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h | 83
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c | 1578 ++
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h | 163
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h | 105
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h | 62
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c | 620
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h | 71
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h | 56
+ drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c | 2855 +++
+ drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h | 89
+ drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h | 284
+ drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c | 1047 +
+ drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h | 70
+ drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h | 74
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h | 96
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c | 3174 ++++
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h | 111
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h | 267
+ drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c | 682
+ drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h | 63
+ drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h | 62
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h | 152
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c | 3752 ++++
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h | 96
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h | 248
+ drivers/media/nomadik_mm/hcl/sva/sva.c | 1827 ++
+ drivers/media/nomadik_mm/hcl/sva/sva.h | 2148 ++
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c | 1701 ++
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h | 93
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h | 134
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c | 3573 ++++
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h | 403
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h | 359
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c | 19
+ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c | 2478 +++
+ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h | 89
+ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h | 278
+ drivers/media/nomadik_mm/opengl/Makefile | 18
+ drivers/media/nomadik_mm/opengl/ogl.c | 565
+ drivers/media/nomadik_mm/opengl/ogl.h | 65
+ drivers/media/nomadik_mm/opengl/ogl_ioctl.h | 56
+ drivers/media/nomadik_mm/saa/Makefile | 20
+ drivers/media/nomadik_mm/saa/README | 72
+ drivers/media/nomadik_mm/saa/nomadik-fwload.c | 229
+ drivers/media/nomadik_mm/saa/nomadik-fwload.h | 47
+ drivers/media/nomadik_mm/saa/nomadik-saa.c | 4406 +++++
+ drivers/media/nomadik_mm/saa/nomadik-saa.h | 204
+ drivers/media/nomadik_mm/saa/saaioctl.h | 498
+ drivers/media/nomadik_mm/sva/Makefile | 58
+ drivers/media/nomadik_mm/sva/nomadik_camera.h | 206
+ drivers/media/nomadik_mm/sva/nomadik_defs.h | 76
+ drivers/media/nomadik_mm/sva/nomadik_pepperpot.c | 1189 +
+ drivers/media/nomadik_mm/sva/nomadik_pepperpot.h | 153
+ drivers/media/nomadik_mm/sva/nomadik_sva.c | 4951 ++++++
+ drivers/media/nomadik_mm/sva/nomadik_sva.h | 225
+ drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c | 432
+ drivers/media/nomadik_mm/sva/nomadik_sva_services.h | 3826 +++++
+ drivers/media/nomadik_mm/sva/nomadik_sva_utils.c | 964 +
+ drivers/media/nomadik_mm/sva/nomadik_sva_utils.h | 49
+ drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c | 6984 +++++++++
+ drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h | 589
+ drivers/media/video/Kconfig | 7
+ drivers/media/video/Makefile | 8
+ drivers/media/video/hcl_defs.h | 280
+ drivers/media/video/nomadik_camera.h | 206
+ drivers/media/video/nomadik_defs.h | 76
+ drivers/media/video/nomadik_sva.h | 225
+ drivers/media/video/nomadik_sva_services.h | 3832 +++++
+ drivers/media/video/nomadik_sva_utils.h | 49
+ drivers/media/video/platform_os.h | 55
+ drivers/media/video/sva.h | 2148 ++
+ drivers/media/video/v4l2-nomadik.c | 1590 ++
+ drivers/media/video/v4l2-nomadik.h | 70
+ drivers/misc/Kconfig | 27
+ drivers/misc/Makefile | 4
+ drivers/misc/batt-nomadik.c | 1307 +
+ drivers/misc/etm-nomadik.c | 207
+ drivers/misc/pexp-nomadik.c | 2847 +++
+ drivers/misc/sif-nomadik.c | 560
+ drivers/mmc/Kconfig | 27
+ drivers/mmc/Makefile | 9
+ drivers/mmc/mmc-nomadik.c | 1435 +
+ drivers/mtd/maps/Kconfig | 7
+ drivers/mtd/maps/Makefile | 11
+ drivers/mtd/maps/norflash-nomadik.c | 411
+ drivers/mtd/nand/Kconfig | 6
+ drivers/mtd/nand/Makefile | 5
+ drivers/mtd/nand/nandflash-nomadik.c | 296
+ drivers/mtd/onenand/Kconfig | 38
+ drivers/mtd/onenand/Makefile | 3
+ drivers/mtd/onenand/generic.c | 62
+ drivers/mtd/onenand/onenand_base.c | 1139 +
+ drivers/mtd/onenand/onenand_bbt.c | 33
+ drivers/mtd/onenand/onenand_sim.c | 495
+ drivers/net/Makefile | 1
+ drivers/net/kgdboe.c | 294
+ drivers/net/smc91x.c | 100
+ drivers/net/smc91x.h | 133
+ drivers/serial/amba-pl011.c | 101
+ drivers/spi/Kconfig | 8
+ drivers/spi/Makefile | 2
+ drivers/spi/spi-nomadik.c | 1000 +
+ drivers/usb/Kconfig | 2
+ drivers/usb/Makefile | 1
+ drivers/usb/gadget/file_storage.c | 15
+ drivers/usb/nomadik/Kconfig | 176
+ drivers/usb/nomadik/Makefile | 97
+ drivers/usb/nomadik/board.h | 58
+ drivers/usb/nomadik/debug.h | 104
+ drivers/usb/nomadik/dma.h | 308
+ drivers/usb/nomadik/g_ep0.c | 858 +
+ drivers/usb/nomadik/logx | 1
+ drivers/usb/nomadik/musb_bus_direct.c | 371
+ drivers/usb/nomadik/musb_cross.h | 131
+ drivers/usb/nomadik/musb_debug.c | 190
+ drivers/usb/nomadik/musb_epdescriptors.h | 48
+ drivers/usb/nomadik/musb_epfifocfg.c | 429
+ drivers/usb/nomadik/musb_hcd.c | 869 +
+ drivers/usb/nomadik/musb_host.c | 2791 +++
+ drivers/usb/nomadik/musb_host.h | 101
+ drivers/usb/nomadik/musb_ioctl.c | 321
+ drivers/usb/nomadik/musb_ioctl.h | 32
+ drivers/usb/nomadik/musb_plat_uds.c | 2306 +++
+ drivers/usb/nomadik/musb_procfs.c | 413
+ drivers/usb/nomadik/musb_virthub.c | 840 +
+ drivers/usb/nomadik/musb_virthub.h | 240
+ drivers/usb/nomadik/musbdefs.h | 828 +
+ drivers/usb/nomadik/musbhdrc.h | 315
+ drivers/usb/nomadik/musbhsfc.h | 150
+ drivers/usb/nomadik/nomadik_udc.c | 2845 +++
+ drivers/usb/nomadik/nomadik_udc.h | 663
+ drivers/usb/nomadik/otg_func.c | 196
+ drivers/usb/nomadik/otg_pwm.c | 46
+ drivers/usb/nomadik/plat_arc.h | 92
+ drivers/usb/nomadik/plat_cnf.h | 208
+ drivers/video/Makefile | 1
+ drivers/video/amba-clcd.c | 115
+ drivers/video/fbmem.c | 1
+ drivers/video/nomadik/Makefile | 15
+ drivers/video/nomadik/hcl/debug.h | 313
+ drivers/video/nomadik/hcl/hcl_defs.h | 286
+ drivers/video/nomadik/hcl/platform_os.h | 79
+ drivers/video/nomadik/hcl/sga.c | 3161 ++++
+ drivers/video/nomadik/hcl/sga.h | 937 +
+ drivers/video/nomadik/hcl/sga_irq.c | 206
+ drivers/video/nomadik/hcl/sga_irq.h | 99
+ drivers/video/nomadik/hcl/sga_irqp.h | 239
+ drivers/video/nomadik/hcl/sga_p.h | 175
+ drivers/video/nomadik/sga_defs.h | 87
+ drivers/video/nomadik/sga_err.h | 45
+ drivers/video/nomadik/sga_interface.h | 119
+ drivers/video/nomadik/sga_ioctlfns.c | 473
+ drivers/video/nomadik/sga_ioctlfns.h | 50
+ drivers/video/nomadik/sga_main.c | 651
+ drivers/video/nomadik/sga_main.h | 123
+ drivers/video/nomadik/sga_typs.h | 37
+ fs/Kconfig | 4
+ fs/Makefile | 3
+ fs/proc/proc_misc.c | 42
+ fs/yaffs2/Kconfig | 156
+ fs/yaffs2/Makefile | 10
+ fs/yaffs2/devextras.h | 264
+ fs/yaffs2/moduleconfig.h | 65
+ fs/yaffs2/yaffs_checkptrw.c | 404
+ fs/yaffs2/yaffs_checkptrw.h | 35
+ fs/yaffs2/yaffs_ecc.c | 331
+ fs/yaffs2/yaffs_ecc.h | 44
+ fs/yaffs2/yaffs_fs.c | 2297 +++
+ fs/yaffs2/yaffs_guts.c | 7532 ++++++++++
+ fs/yaffs2/yaffs_guts.h | 904 +
+ fs/yaffs2/yaffs_mtdif.c | 241
+ fs/yaffs2/yaffs_mtdif.h | 27
+ fs/yaffs2/yaffs_mtdif1.c | 369
+ fs/yaffs2/yaffs_mtdif1.h | 28
+ fs/yaffs2/yaffs_mtdif2.c | 232
+ fs/yaffs2/yaffs_mtdif2.h | 29
+ fs/yaffs2/yaffs_nand.c | 134
+ fs/yaffs2/yaffs_nand.h | 44
+ fs/yaffs2/yaffs_nandemul2k.h | 39
+ fs/yaffs2/yaffs_packedtags1.c | 52
+ fs/yaffs2/yaffs_packedtags1.h | 37
+ fs/yaffs2/yaffs_packedtags2.c | 182
+ fs/yaffs2/yaffs_packedtags2.h | 38
+ fs/yaffs2/yaffs_qsort.c | 160
+ fs/yaffs2/yaffs_qsort.h | 23
+ fs/yaffs2/yaffs_tagscompat.c | 530
+ fs/yaffs2/yaffs_tagscompat.h | 40
+ fs/yaffs2/yaffs_tagsvalidity.c | 28
+ fs/yaffs2/yaffs_tagsvalidity.h | 24
+ fs/yaffs2/yaffsinterface.h | 21
+ fs/yaffs2/yportenv.h | 200
+ include/asm-arm/arch-nomadik/audiocodec.h | 444
+ include/asm-arm/arch-nomadik/bits.h | 61
+ include/asm-arm/arch-nomadik/debug-macro.S | 38
+ include/asm-arm/arch-nomadik/debug.h | 148
+ include/asm-arm/arch-nomadik/defs.h | 245
+ include/asm-arm/arch-nomadik/dma.h | 362
+ include/asm-arm/arch-nomadik/entry-macro.S | 210
+ include/asm-arm/arch-nomadik/epio.h | 24
+ include/asm-arm/arch-nomadik/fsmc.h | 203
+ include/asm-arm/arch-nomadik/gpio.h | 529
+ include/asm-arm/arch-nomadik/hardware.h | 107
+ include/asm-arm/arch-nomadik/i2c.h | 419
+ include/asm-arm/arch-nomadik/io.h | 37
+ include/asm-arm/arch-nomadik/irqs.h | 137
+ include/asm-arm/arch-nomadik/kpd.h | 56
+ include/asm-arm/arch-nomadik/memory.h | 41
+ include/asm-arm/arch-nomadik/mmc.h | 234
+ include/asm-arm/arch-nomadik/msp-spi.h | 343
+ include/asm-arm/arch-nomadik/msp.h | 322
+ include/asm-arm/arch-nomadik/mtu.h | 90
+ include/asm-arm/arch-nomadik/nandflash.h | 42
+ include/asm-arm/arch-nomadik/ndk10_devices.h | 160
+ include/asm-arm/arch-nomadik/ndk15_devices.h | 248
+ include/asm-arm/arch-nomadik/ndk15c02_devices.h | 169
+ include/asm-arm/arch-nomadik/nhk15_devices.h | 131
+ include/asm-arm/arch-nomadik/param.h | 19
+ include/asm-arm/arch-nomadik/pexp.h | 355
+ include/asm-arm/arch-nomadik/power.h | 180
+ include/asm-arm/arch-nomadik/smp.h | 19
+ include/asm-arm/arch-nomadik/spi.h | 521
+ include/asm-arm/arch-nomadik/ssp-spi.h | 280
+ include/asm-arm/arch-nomadik/stn8810_devices.h | 120
+ include/asm-arm/arch-nomadik/stn8815_devices.h | 165
+ include/asm-arm/arch-nomadik/stw5094ap.h | 176
+ include/asm-arm/arch-nomadik/stw5095.h | 1387 +
+ include/asm-arm/arch-nomadik/sva.h | 43
+ include/asm-arm/arch-nomadik/system.h | 62
+ include/asm-arm/arch-nomadik/timex.h | 71
+ include/asm-arm/arch-nomadik/touchp.h | 145
+ include/asm-arm/arch-nomadik/touchp2003.h | 42
+ include/asm-arm/arch-nomadik/udc.h | 490
+ include/asm-arm/arch-nomadik/uncompress.h | 71
+ include/asm-arm/arch-nomadik/vmalloc.h | 32
+ include/asm-arm/kgdb.h | 91
+ include/asm-arm/system.h | 41
+ include/asm-generic/kgdb.h | 34
+ include/linux/amba/clcd.h | 24
+ include/linux/dwarf2-lang.h | 300
+ include/linux/dwarf2.h | 775 +
+ include/linux/i2c.h | 13
+ include/linux/kgdb.h | 271
+ include/linux/miscdevice.h | 1
+ include/linux/module.h | 28
+ include/linux/mtd/bbm.h | 11
+ include/linux/mtd/mtd.h | 1
+ include/linux/mtd/nand.h | 52
+ include/linux/mtd/onenand.h | 31
+ include/linux/mtd/onenand_regs.h | 8
+ include/linux/netpoll.h | 2
+ include/linux/usb.h | 4
+ include/linux/v4l2-nomadikdefs.h | 12
+ include/linux/videodev2.h | 11
+ init/Kconfig | 15
+ kernel/Makefile | 1
+ kernel/kgdb.c | 1963 ++
+ kernel/module.c | 216
+ kernel/pid.c | 11
+ kernel/power/main.c | 2
+ kernel/sched.c | 6
+ kernel/softlockup.c | 4
+ kernel/timer.c | 8
+ lib/Kconfig.debug | 79
+ net/core/netpoll.c | 5
+ net/sunrpc/xprtsock.c | 5
+ scripts/Makefile | 1
+ scripts/Makefile.modpost | 2
+ scripts/dwarfh.awk | 19
+ scripts/kconfig/Makefile | 32
+ scripts/ksymhash/Makefile | 35
+ scripts/ksymhash/elflib.c | 164
+ scripts/ksymhash/elflib.h | 142
+ scripts/ksymhash/empty.c | 1
+ scripts/ksymhash/ksymhash.c | 126
+ scripts/ksymhash/mk_elfconfig.c | 66
+ scripts/mod/modpost.c | 23
+ sound/Kconfig | 36
+ sound/Makefile | 9
+ sound/arm/Kconfig | 11
+ sound/arm/Makefile | 3
+ sound/arm/nomadik_alsa.c | 1038 +
+ sound/arm/nomadik_alsa.h | 83
+ sound/nomadik_stw5094.c | 2280 +++
+ sound/nomadik_stw5095.c | 3529 ++++
+ 514 files changed, 244969 insertions(+), 622 deletions(-)
+
+--- linux-2.6.20.orig/.gitignore
++++ /dev/null
+@@ -1,47 +0,0 @@
+-#
+-# NOTE! Don't add files that are generated in specific
+-# subdirectories here. Add them in the ".gitignore" file
+-# in that subdirectory instead.
+-#
+-# Normal rules
+-#
+-.*
+-*.o
+-*.a
+-*.s
+-*.ko
+-*.so
+-*.mod.c
+-*.i
+-*.lst
+-*.symtypes
+-
+-#
+-# Top-level generic files
+-#
+-tags
+-TAGS
+-vmlinux*
+-System.map
+-Module.symvers
+-
+-#
+-# Generated include files
+-#
+-include/asm
+-include/asm-*/asm-offsets.h
+-include/config
+-include/linux/autoconf.h
+-include/linux/compile.h
+-include/linux/version.h
+-include/linux/utsrelease.h
+-
+-# stgit generated dirs
+-patches-*
+-
+-# quilt's files
+-patches
+-series
+-
+-# cscope files
+-cscope.*
+--- linux-2.6.20.orig/Documentation/DocBook/Makefile
++++ linux-2.6.20/Documentation/DocBook/Makefile
+@@ -9,11 +9,12 @@
+ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
+ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
+ procfs-guide.xml writing_usb_driver.xml \
+ kernel-api.xml filesystems.xml lsm.xml usb.xml \
+ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
+- genericirq.xml
++ genericirq.xml \
++ kgdb.xml
- case RTC_RD_TIME:
-diff -Nauprw linux-2.6.20/arch/arm/configs/ndk10_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk10_defconfig
---- linux-2.6.20/arch/arm/configs/ndk10_defconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/configs/ndk10_defconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1205 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.20
-+# Thu Aug 16 17:17:58 2007
-+#
-+CONFIG_ARM=y
-+# CONFIG_GENERIC_TIME is not set
-+CONFIG_MMU=y
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ ###
+ # The build process is as follows (targets):
+ # (xmldocs)
+ # file.tmpl --> file.xml +--> file.ps (psdocs)
+--- /dev/null
++++ linux-2.6.20/Documentation/DocBook/kgdb.tmpl
+@@ -0,0 +1,234 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
++ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_LOCK_KERNEL=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
++<book id="kgdbInternals">
++ <bookinfo>
++ <title>KGDB Internals</title>
+
-+#
-+# General setup
-+#
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_IPC_NS is not set
-+# CONFIG_POSIX_MQUEUE is not set
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+# CONFIG_TASKSTATS is not set
-+# CONFIG_UTS_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_INITRAMFS_SOURCE=""
-+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-+CONFIG_SYSCTL=y
-+CONFIG_EMBEDDED=y
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_ALL is not set
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_EPOLL=y
-+CONFIG_SHMEM=y
-+CONFIG_SLAB=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+# CONFIG_SLOB is not set
++ <authorgroup>
++ <author>
++ <firstname>Tom</firstname>
++ <surname>Rini</surname>
++ <affiliation>
++ <address>
++ <email>trini@kernel.crashing.org</email>
++ </address>
++ </affiliation>
++ </author>
++ </authorgroup>
+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+# CONFIG_MODULE_FORCE_UNLOAD is not set
-+# CONFIG_MODVERSIONS is not set
-+# CONFIG_MODULE_SRCVERSION_ALL is not set
-+# CONFIG_KMOD is not set
++ <authorgroup>
++ <author>
++ <firstname>Amit S.</firstname>
++ <surname>Kale</surname>
++ <affiliation>
++ <address>
++ <email>amitkale@linsyssoft.com</email>
++ </address>
++ </affiliation>
++ </author>
++ </authorgroup>
+
-+#
-+# Block layer
-+#
-+CONFIG_BLOCK=y
-+# CONFIG_LBD is not set
-+# CONFIG_BLK_DEV_IO_TRACE is not set
-+# CONFIG_LSF is not set
++ <copyright>
++ <year>2004-2005</year>
++ <holder>MontaVista Software, Inc.</holder>
++ </copyright>
++ <copyright>
++ <year>2004</year>
++ <holder>Amit S. Kale</holder>
++ </copyright>
+
-+#
-+# IO Schedulers
-+#
-+CONFIG_IOSCHED_NOOP=y
-+CONFIG_IOSCHED_AS=y
-+CONFIG_IOSCHED_DEADLINE=y
-+CONFIG_IOSCHED_CFQ=y
-+CONFIG_DEFAULT_AS=y
-+# CONFIG_DEFAULT_DEADLINE is not set
-+# CONFIG_DEFAULT_CFQ is not set
-+# CONFIG_DEFAULT_NOOP is not set
-+CONFIG_DEFAULT_IOSCHED="anticipatory"
++ <legalnotice>
++ <para>
++ This file is licensed under the terms of the GNU General Public License
++ version 2. This program is licensed "as is" without any warranty of any
++ kind, whether express or implied.
++ </para>
+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_AAEC2000 is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_REALVIEW is not set
-+# CONFIG_ARCH_VERSATILE is not set
-+# CONFIG_ARCH_AT91 is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_EP93XX is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_NETX is not set
-+CONFIG_ARCH_NOMADIK=y
-+# CONFIG_ARCH_H720X is not set
-+# CONFIG_ARCH_IMX is not set
-+# CONFIG_ARCH_IOP32X is not set
-+# CONFIG_ARCH_IOP33X is not set
-+# CONFIG_ARCH_IOP13XX is not set
-+# CONFIG_ARCH_IXP4XX is not set
-+# CONFIG_ARCH_IXP2000 is not set
-+# CONFIG_ARCH_IXP23XX is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_S3C2410 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_LH7A40X is not set
-+# CONFIG_ARCH_OMAP is not set
-+CONFIG_NOMADIK_NDK10_CUT_A1=y
-+# CONFIG_NOMADIK_NDK10_CUT_B06 is not set
-+# CONFIG_NOMADIK_NDK10_CUT_B0 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set
-+# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set
-+CONFIG_NOMADIK_TARGET="NDK10_Cut_A1"
-+CONFIG_NOMADIK_SOC="stn8810"
-+CONFIG_NOMADIK_PLATFORM="ndk10"
-+CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
-+CONFIG_NOMADIK_NDK10=y
-+CONFIG_NOMADIK_NDK10_CUTA=y
-+CONFIG_NOMADIK_GPIO=y
-+CONFIG_GPIO_PROC=y
-+CONFIG_NOMADIK_DMA=y
-+CONFIG_NOMADIK_SSP=m
-+CONFIG_NOMADIK_MSP=m
-+CONFIG_NOMADIK_MTU=m
-+CONFIG_NOMADIK_MTU_SYSTEM_TICK=y
-+CONFIG_NOMADIK_RTC=y
-+# CONFIG_NOMADIK_SVA_INIT_MEM is not set
-+CONFIG_NOMADIK_SVA_MEM_SIZE=4
-+# CONFIG_NOMADIK_SAA_INIT_MEM is not set
-+# CONFIG_FB_NOMADIK_VGA is not set
-+# CONFIG_FB_NOMADIK_CRT is not set
-+CONFIG_FB_NOMADIK_QVGA_PORTRAIT=y
-+# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set
-+# CONFIG_FB_NOMADIK_PANEL_8BPP is not set
-+CONFIG_FB_NOMADIK_PANEL_16BPP=y
-+# CONFIG_FB_NOMADIK_PANEL_24BPP is not set
-+CONFIG_SGA_INST_BUFFER_2=y
-+# CONFIG_SGA_INST_BUFFER_20 is not set
-+CONFIG_SGA_INST_BUFFER_NUM=2
-+CONFIG_FB_NOMADIK_PANEL_BPP=16
-+CONFIG_FB_NOMADIK_PANEL_NAME="QVGA_Portrait"
-+CONFIG_FB_NOMADIK_PANEL_XRES=240
-+CONFIG_FB_NOMADIK_PANEL_YRES=320
-+CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x13
-+CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x2f
-+CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x04
-+CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x0f
-+CONFIG_FB_NOMADIK_PANEL_HSLEN=0x13
-+CONFIG_FB_NOMADIK_PANEL_VSLEN=0x04
-+CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x00ef1804
++ </legalnotice>
++ </bookinfo>
+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_ARM920T is not set
-+CONFIG_CPU_ARM926T=y
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1022 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_V6 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
++<toc></toc>
++ <chapter id="Introduction">
++ <title>Introduction</title>
++ <para>
++ kgdb is a source level debugger for linux kernel. It is used along
++ with gdb to debug a linux kernel. Kernel developers can debug a kernel
++ similar to application programs with the use of kgdb. It makes it
++ possible to place breakpoints in kernel code, step through the code
++ and observe variables.
++ </para>
++ <para>
++ Two machines are required for using kgdb. One of these machines is a
++ development machine and the other is a test machine. The machines are
++ typically connected through a serial line, a null-modem cable which
++ connects their serial ports. It is also possible however, to use an
++ ethernet connection between the machines. The kernel to be debugged
++ runs on the test machine. gdb runs on the development machine. The
++ serial line or ethernet connection is used by gdb to communicate to
++ the kernel being debugged.
++ </para>
++ </chapter>
++ <chapter id="CompilingAKernel">
++ <title>Compiling a kernel</title>
++ <para>
++ To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
++ and then select "KGDB: kernel debugging with remote gdb".
++ </para>
++ <para>
++ The first choice for I/O is <symbol>CONFIG_KGDB_ONLY_MODULES</symbol>.
++ This means that you will only be able to use KGDB after loading a
++ kernel module that defines how you want to be able to talk with
++ KGDB. There are two other choices (more on some architectures) that
++ can be enabled as modules later, if not picked here.
++ </para>
++ <para>The first of these is <symbol>CONFIG_KGDB_8250_NOMODULE</symbol>.
++ This has sub-options such as <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol>
++ which toggles choosing the serial port by ttyS number or by specifying
++ a port and IRQ number.
++ </para>
++ <para>
++ The second of these choices on most systems for I/O is
++ <symbol>CONFIG_KGDBOE</symbol>. This requires that the machine to be
++ debugged has an ethernet card which supports the netpoll API, such as
++ the cards supported by <symbol>CONFIG_E100</symbol>. There are no
++ sub-options for this, but a kernel command line option is required.
++ </para>
++ </chapter>
++ <chapter id="BootingTheKernel">
++ <title>Booting the kernel</title>
++ <para>
++ The Kernel command line option <constant>kgdbwait</constant> makes kgdb
++ wait for gdb connection during booting of a kernel. If the
++ <symbol>CONFIG_KGDB_8250</symbol> driver is used (or if applicable,
++ another serial driver) this breakpoint will happen very early on, before
++ console output. If you wish to change serial port information and you
++ have enabled both <symbol>CONFIG_KGDB_8250</symbol> and
++ <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> then you must pass the option
++ <constant>kgdb8250=<io or mmio>,<address>,<baud
++ rate>,<irq></constant> before <constant>kgdbwait</constant>.
++ The values <constant>io</constant> or <constant>mmio</constant> refer to
++ if the address being passed next needs to be memory mapped
++ (<constant>mmio</constant>) or not. The <constant>address</constant> must
++ be passed in hex and is the hardware address and will be remapped if
++ passed as <constant>mmio</constant>. The value
++ <constant>baud rate</constant> and <constant>irq</constant> are base-10.
++ The supported values for <constant>baud rate</constant> are
++ <constant>9600</constant>, <constant>19200</constant>,
++ <constant>38400</constant>, <constant>57600</constant>, and
++ <constant>115200</constant>.
++ </para>
++ <para>
++ To have KGDB stop the kernel and wait, with the compiled values for the
++ serial driver, pass in: <constant>kgdbwait</constant>.
++ </para>
++ <para>
++ To specify the values of the serial port at boot:
++ <constant>kgdb8250=io,3f8,115200,3</constant>.
++ On IA64 this could also be:
++ <constant>kgdb8250=mmio,0xff5e0000,115200,74</constant>
++ And to have KGDB also stop the kernel and wait for GDB to connect, pass in
++ <constant>kgdbwait</constant> after this arguement.
++ </para>
++ <para>
++ To configure the <symbol>CONFIG_KGDBOE</symbol> driver, pass in
++ <constant>kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]</constant>
++ where:
++ <itemizedlist>
++ <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem>
++ <listitem><para>src-ip: source IP to use (interface address)</para></listitem>
++ <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem>
++ <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem>
++ <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem>
++ <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem>
++ </itemizedlist>
++ </para>
++ <para>
++ The <symbol>CONFIG_KGDBOE</symbol> driver can be reconfigured at run
++ time, if <symbol>CONFIG_SYSFS</symbol> and
++ <symbol>CONFIG_MODULES</symbol> by echo'ing a new config string to
++ <constant>/sys/module/kgdboe/parameter/kgdboe</constant>. The
++ driver can be unconfigured with the special string
++ <constant>not_configured</constant>.
++ </para>
++ </chapter>
++ <chapter id="ConnectingGDB">
++ <title>Connecting gdb</title>
++ <para>
++ If you have used any of the methods to have KGDB stop and create
++ an initial breakpoint described in the previous chapter, kgdb prints
++ the message "Waiting for connection from remote gdb..." on the console
++ and waits for connection from gdb. At this point you connect gdb to kgdb.
++ </para>
++ <para>
++ Example (serial):
++ </para>
++ <programlisting>
++ % gdb ./vmlinux
++ (gdb) set remotebaud 115200
++ (gdb) target remote /dev/ttyS0
++ </programlisting>
++ <para>
++ Example (ethernet):
++ </para>
++ <programlisting>
++ % gdb ./vmlinux
++ (gdb) target remote udp:192.168.2.2:6443
++ </programlisting>
++ <para>
++ Once connected, you can debug a kernel the way you would debug an
++ application program.
++ </para>
++ </chapter>
++ <chapter id="CommonBackEndReq">
++ <title>The common backend (required)</title>
++ <para>
++ There are a few flags which must be set on every architecture in
++ their <asm/kgdb.h> file. These are:
++ <itemizedlist>
++ <listitem>
++ <para>
++ NUMREGBYTES: The size in bytes of all of the registers, so
++ that we can ensure they will all fit into a packet.
++ </para>
++ <para>
++ BUFMAX: The size in bytes of the buffer GDB will read into.
++ This must be larger than NUMREGBYTES.
++ </para>
++ <para>
++ CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call
++ flush_cache_range or flush_icache_range. On some architectures,
++ these functions may not be safe to call on SMP since we keep other
++ CPUs in a holding pattern.
++ </para>
++ </listitem>
++ </itemizedlist>
++ </para>
++ <para>
++ There are also the following functions for the common backend,
++ found in kernel/kgdb.c that must be supplied by the
++ architecture-specific backend. No weak version of these is provided.
++ </para>
++!Iinclude/linux/kgdb.h
++ </chapter>
++ <chapter id="CommonBackEndOpt">
++ <title>The common backend (optional)</title>
++ <para>
++ These functions are part of the common backend, found in kernel/kgdb.c
++ and are optionally implemented. Some functions (with _hw_ in the name)
++ end up being required on arches which use hardware breakpoints.
++ </para>
++!Ikernel/kgdb.c
++ </chapter>
++ <chapter id="DriverSpecificFunctions">
++ <title>Driver-Specific Functions</title>
++ <para>
++ Some of the I/O drivers have additional functions that can be
++ called, that are specific to the driver. Calls from other places
++ to these functions must be wrapped in #ifdefs for the driver in
++ question.
++ </para>
++!Idrivers/serial/8250_kgdb.c
++ </chapter>
++</book>
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
+@@ -0,0 +1,111 @@
++Filename: ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
++Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner: STMicroelectronics
++Purpose:
++ This HOWTO explains guidlines for addition of new Nomadik
++ board support to the kernel source code
++===============================================================================
+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+CONFIG_ICST525=y
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+CONFIG_ISA_DMA_API=y
++Nomadik BSP kernel file naming conventions
++============================================
++It is strongly recommended to follow below filename conventions while adding
++new board support for Nomadik
++1. All the Nomadik architecture specific code must be in mach-nomadik and
++ arch-nomadik folders in a kernel tree.
++2. Generic and Nomadik specific device drives may be located into the respective
++ folder in the kernel source tree (ex. nomadik keypad driver in
++ drivers/input/keyboard/kpd-nomadik.c)
++3. all Nomadik specific files in mach-nomadik and arch-nomadik folders should
++ be named as <comp>.c/h
++ (ex. gpio.h, msp.c)
++4. all Nomadik platform specific files are named as <platform>_<purpose>.c/h
++ (ex. ndk10_devices.c, ndk15_devices.h)
++5. all Nomadik soc specific files are named as <soc>_<purpose>.c/h
++ (ex. stn8810_devices.h, stn8815_devices.c)
+
-+#
-+# PCCARD (PCMCIA/CardBus) support
-+#
-+# CONFIG_PCCARD is not set
++Important definations
++==============================
++1. target: It is a unique identity to describe supported board with a specific
++ board version and specific SOC version.
++ target is created by combination of board (i.e. platform) and
++ Nomadik chip version (i.e. soc)
+
-+#
-+# Kernel Features
-+#
-+CONFIG_PREEMPT=y
-+CONFIG_NO_IDLE_HZ=y
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+CONFIG_OABI_COMPAT=y
-+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
-+CONFIG_SELECT_MEMORY_MODEL=y
-+CONFIG_FLATMEM_MANUAL=y
-+# CONFIG_DISCONTIGMEM_MANUAL is not set
-+# CONFIG_SPARSEMEM_MANUAL is not set
-+CONFIG_FLATMEM=y
-+CONFIG_FLAT_NODE_MEM_MAP=y
-+# CONFIG_SPARSEMEM_STATIC is not set
-+CONFIG_SPLIT_PTLOCK_CPUS=4096
-+# CONFIG_RESOURCES_64BIT is not set
-+CONFIG_ALIGNMENT_TRAP=y
++2. platform: It is refered for board to be supported.
++ One plaform may be supported by several targets
++ One plaform may be supported by several socs
+
-+#
-+# Boot options
-+#
-+CONFIG_ZBOOT_ROM_TEXT=0x0
-+CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
-+# CONFIG_XIP_KERNEL is not set
++3. soc: It is refered for the Nomadik chip version to be suported.
++ same soc may be supported on several platforms
+
-+#
-+# CPU Frequency scaling
-+#
-+# CONFIG_CPU_FREQ is not set
++Hence any Nomadik borad is identified as a "target" and supported by "soc"
++ specific code and "platform" specific code well interfaced with generic
++ code.
+
-+#
-+# Floating point emulation
-+#
++Device driver Support for Nomadik:
++====================================
++1. All the drivers suported on a target can be either SOC or platform specific
++2. A platform specific code for all supported driver will be refered from a
++ single file <platform_name>_devices.c through device specific interface.
++3. A Nomadik chip specific code for all supported driver will be refered from a
++ single file <soc_name>_devices.c through device specific interface.
++4. Each device specific header file <pltfomr_name>_devices.h and
++ <soc_name>_devices.h must be maintained to share a common hardware
++ parameters across the drivers. Those two files are included in
++ asm/arch/hardware.h which is further refered through asm/hardware.h
++ Hence any kernel code seeking for hardware specific information (like
++ base address, irqnos) can be made available by just including
++ <asm/hardware.h>
++5. Each header file described here should have relevent declaration related to
++ the scope of its usage. ex. <platform_name>_devices.h should only have
++ platforms specific declration.
+
-+#
-+# At least one emulation must be selected
-+#
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_NWFPE_XP is not set
-+# CONFIG_FPE_FASTFPE is not set
-+# CONFIG_VFP is not set
++Any Nomadik target can be supported by following set of files:-
++ arch/arch/mach-nomadik/<soc_name>_devices.c
++ inclue/asm-arm/arch-nomadik/<soc_name>_devices.h
++ arch/arch/mach-nomadik/<platform_name>_devices.c
++ inclue/asm-arm/arch-nomadik/<platform_name>_devices.h
+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
++But Generally, New board support will be added for already suported SOCs
++hence, to add support for any new Nomadik target only three files need to be
++added, those are:-
++ arch/arch/mach-nomadik/<target_name>_Kconfig
++ arch/arch/mach-nomadik/<platform_name>_devices.c
++ inclue/asm-arm/arch0-nomadik/<platform_name>_devices.h
+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+# CONFIG_APM is not set
++Steps to follow to add new target support for Nomadik
++========================================================
++1. Add ./arch/arm/mach-nomadik/<target_name>_Kconfig file for board
++ configuration, <target_name> specified here will reflect as machine name.
+
-+#
-+# Networking
-+#
-+CONFIG_NET=y
++ During make config/menuconfig arch/arm/mach-nomadik/Kconfig will be
++ checked, and if is not found, it will be created automatically using
++ all <target_name>_Kconfig files and Kconfig_nomadik file.
++ 1. <target_name>_Kconfig file contain board specific configuration
++ 2. Kconfig_nomadik contains generic configuration for all nomadik
++ platforms
++ for details refer provided ndk10_cut_a1_Kconfig file
+
-+#
-+# Networking options
-+#
-+# CONFIG_NETDEBUG is not set
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+CONFIG_UNIX=y
-+CONFIG_XFRM=y
-+# CONFIG_XFRM_USER is not set
-+# CONFIG_XFRM_SUB_POLICY is not set
-+# CONFIG_NET_KEY is not set
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_INET_AH is not set
-+# CONFIG_INET_ESP is not set
-+# CONFIG_INET_IPCOMP is not set
-+# CONFIG_INET_XFRM_TUNNEL is not set
-+# CONFIG_INET_TUNNEL is not set
-+CONFIG_INET_XFRM_MODE_TRANSPORT=y
-+CONFIG_INET_XFRM_MODE_TUNNEL=y
-+CONFIG_INET_XFRM_MODE_BEET=y
-+CONFIG_INET_DIAG=y
-+CONFIG_INET_TCP_DIAG=y
-+# CONFIG_TCP_CONG_ADVANCED is not set
-+CONFIG_TCP_CONG_CUBIC=y
-+CONFIG_DEFAULT_TCP_CONG="cubic"
-+# CONFIG_TCP_MD5SIG is not set
-+CONFIG_IPV6=m
-+# CONFIG_IPV6_PRIVACY is not set
-+# CONFIG_IPV6_ROUTER_PREF is not set
-+# CONFIG_INET6_AH is not set
-+# CONFIG_INET6_ESP is not set
-+# CONFIG_INET6_IPCOMP is not set
-+# CONFIG_IPV6_MIP6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-+CONFIG_INET6_XFRM_MODE_TUNNEL=m
-+CONFIG_INET6_XFRM_MODE_BEET=m
-+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-+CONFIG_IPV6_SIT=m
-+# CONFIG_IPV6_TUNNEL is not set
-+# CONFIG_IPV6_MULTIPLE_TABLES is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+# CONFIG_NETFILTER is not set
++2. Add ./arch/arm/mach-nomadik/<platform_name>_devices.c file
++ This file contains all the platfrom specific functions and data
++ structures used by rest of the code. Any driver suported for Nomadik
++ platform must access all the paramters through this file
++ (for ex. base addres, irq number and other plaform specific data
++ structures and function)
++ It is recommended to refer such file for already suported platform
+
-+#
-+# DCCP Configuration (EXPERIMENTAL)
-+#
-+# CONFIG_IP_DCCP is not set
++3. Add ./include/asm-arm/arch-nomadik/<platform_name>_devices.h file
++ This file must contain all the declarations for this platform
++ which may be refered by the other drivers and kernel code.
++ Note that this file is refered by some assembly code hence the
++ content of this files must be maintained simple, standard and
++ generic.
++ It is recommended to refer such file for already suported platform
+
-+#
-+# SCTP Configuration (EXPERIMENTAL)
-+#
-+# CONFIG_IP_SCTP is not set
++With the above addition/modification New target support will be available.
++Select newly supported target in kernel configuration, build and execute
++the code on new target
++===============================================================================
+
-+#
-+# TIPC Configuration (EXPERIMENTAL)
-+#
-+# CONFIG_TIPC is not set
-+# CONFIG_ATM is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_LLC2 is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt
+@@ -0,0 +1,106 @@
++This HOWTO esplains mounting the root file system via NFS on Nomadik Platform (nfsroot)
+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
++As you know, all of us spend lot of time in-
++1. Unzip/mount initrd to put the modules/application under test
++2. Copying modules/applications to initrd
++3. Unmount/gzip operation with initrd
++4. Then load huge initrd and kernel each time to target board
++ for execution.
+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+# CONFIG_HAMRADIO is not set
-+# CONFIG_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_IEEE80211 is not set
++So for each time even for a small change we need to repeat this process, and
++downloading and system re-initialization eats lot of our development time.
++Nfsroot is a good solution to overcome above issues.
+
-+#
-+# Device Drivers
-+#
++Root file system can be mounted via NFS (nfsroot) on host and can be accessed
++from your target machin.
+
-+#
-+# Generic Driver Options
-+#
-+CONFIG_STANDALONE=y
-+CONFIG_PREVENT_FIRMWARE_BUILD=y
-+CONFIG_FW_LOADER=y
-+# CONFIG_DEBUG_DRIVER is not set
-+# CONFIG_SYS_HYPERVISOR is not set
++Advantages of this method are:-
++===============================
++1. No need to download ramdiks time to time (saves lot of time)
++2. Since file system is on NFS, runtime results/logs dooes not vanishes
++ in case of nomadik-system crash
++3. Since file system is on NFS, it is transperant to host and target
++4. Making, updating, mounting, unmounting, zipping, unzipping activities
++ associated with ramdisk can be totally avoided (saves lot of time)
++5. Offers comfortable and fast development environment
+
-+#
-+# Connector - unified userspace <-> kernelspace linker
-+#
-+# CONFIG_CONNECTOR is not set
++Host configuration to enable root NFS:-
++========================================
++1. Copy a "target" folder from toolchain at some fixed path on your Linux
++ host
++2. Switch to the dev folder of newly created target folder and create
++ a node for console with command "mknod console c 5 1"
++3. Then swtich to the target folder and create a symbolic link with
++ command "ln -s /bin/busybox linuxrc
++4. FTP and TFTP should be enabled on the host system. You can check the
++ configuration by issuing the following command
+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_CONCAT=y
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
++#> chkconfig --list | grep ftp
+
-+#
-+# User Modules And Translation Layers
-+#
-+CONFIG_MTD_CHAR=y
-+# CONFIG_MTD_BLKDEVS is not set
-+# CONFIG_MTD_BLOCK is not set
-+# CONFIG_MTD_BLOCK_RO is not set
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+# CONFIG_INFTL is not set
-+# CONFIG_RFD_FTL is not set
-+# CONFIG_SSFDC is not set
++Output should look like :-
++vsftpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
++ gssftp: off
++ tftp: on
+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-+CONFIG_MTD_MAP_BANK_WIDTH_1=y
-+CONFIG_MTD_MAP_BANK_WIDTH_2=y
-+CONFIG_MTD_MAP_BANK_WIDTH_4=y
-+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-+CONFIG_MTD_CFI_I1=y
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+CONFIG_MTD_CFI_STAA=y
-+CONFIG_MTD_CFI_UTIL=y
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
++Note: Method of enabling FTP can be different for different versions of Linux.
+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-+# CONFIG_MTD_PHYSMAP is not set
-+CONFIG_MTD_NOMADIK=y
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_PLATRAM is not set
++5. NFS should be enabled. Same can also be checked with the following
++ command
+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_DATAFLASH is not set
-+# CONFIG_MTD_M25P80 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_PHRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLOCK2MTD is not set
++#> chkconfig --list | grep nfs
+
-+#
-+# Disk-On-Chip Device Drivers
-+#
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOC2001PLUS is not set
++Output should looklike
++nfs 0:off 1:off 2:on 3:on 4:on 5:on 6:off
+
-+#
-+# NAND Flash Device Drivers
-+#
-+CONFIG_MTD_NAND=y
-+CONFIG_MTD_NAND_NOMADIK=y
-+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-+# CONFIG_MTD_NAND_ECC_SMC is not set
-+CONFIG_MTD_NAND_IDS=y
-+# CONFIG_MTD_NAND_DISKONCHIP is not set
-+# CONFIG_MTD_NAND_NANDSIM is not set
++6. Also, check the entries of the /etc/xinetd.d/tftp file accordingly.
++ In our case, it is :
+
-+#
-+# OneNAND Flash Device Drivers
-+#
-+# CONFIG_MTD_ONENAND is not set
++service tftp
++{
++ disable = no
++ socket_type = dgram
++ protocol = udp
++ wait = yes
++ user = root
++ server = /usr/sbin/in.tftpd
++ server_args = -T 100000000 -v -c -s
++/local_no_backup
++# server_args = -s /tftpboot
++ per_source = 11
++ cps = 100 2
++ flags = IPv4
++}
+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
++7. Also make the entries in /etc/exports for the file systems that need
++ to be shared. For options used, please refer the man pages of exports.
++ In our case, it is :
+
-+#
-+# Plug and Play support
-+#
++/rtrt *(rw,insecure,no_root_squash,async)
++/local_no_backup/target *(rw,insecure,no_root_squash,async)
+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+# CONFIG_BLK_DEV_LOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_COUNT=16
-+CONFIG_BLK_DEV_RAM_SIZE=46080
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+CONFIG_BLK_DEV_INITRD=y
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
++How to enable NFS feature in your development?
++===============================================
++1. Of cource you need to work on ethernet based environment
++2. Enable ethernet driver in your kernel image
++3. Enable following settings in your kernel image to enable nfsroot
++a. Networking options --->IP: kernel level autoconfiguration
++b. Networking options --->IP: BOOTP support
++c. File systems --->Network File Systems --->NFS file system support
++d. File systems --->Network File Systems --->Provide NFSv3 client support
++e. File systems --->Network File Systems --->Root file system on NFS
++4. Then compile kernel image, prepare uimage and download into the target
++5. Set the command line arguments as -
+
-+#
-+# SCSI device support
-+#
-+# CONFIG_RAID_ATTRS is not set
-+# CONFIG_SCSI is not set
-+# CONFIG_SCSI_NETLINK is not set
++ "set bootargs root=/dev/nfs nfsroot=<HOST_IP_ADDR>:/<PATH>/ramdisk
++ip=<TARGET_IP_ADDR>:<HOST_IP_ADDR>:<GATWAY_IP_ADDR_FOR_TARGET>:255.255.255.0:nomadik:: console=ttyAMA1 mac=<MAC_ADDRESS> init=linuxrc"
+
-+#
-+# Serial ATA (prod) and Parallel ATA (experimental) drivers
-+#
-+# CONFIG_ATA is not set
++for example:-
++"set bootargs root=/dev/nfs nfsroot=10.199.3.88:/local_no_backup/target
++ip=10.199.32.165:10.199.3.88:10.199.32.254:255.255.255.0:NDK10_165::
++mac=00:0D:88:45:5D:A5 console=ttyAMA1,115200n8 init=linuxrc"
+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
++6. And then boot the kernel with command "bootm 0x100000"
++ (initrd address not needed since NFS)
+
-+#
-+# Fusion MPT device support
-+#
-+# CONFIG_FUSION is not set
++Start enjoying the advantages of root NFS
+
-+#
-+# IEEE 1394 (FireWire) support
-+#
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt
+@@ -0,0 +1,66 @@
+
-+#
-+# I2O device support
-+#
++ * 1.1 Nomadik Development Debugging Strategy
++ * ==========================================
++ *
++ * DEBUGGING LEVELS
++ * 0 To disable all debug messages
++ * 1 To enable normal debug macro- nmdk_dbg
++ * 2 To enable flow trace debug macro- nmdk_dbg_ftrace
++ * 4 To enable interrupt and timer debug macroc- nmdk_dbg2
++ * 8 To enable any special debug messages defined by macro- nmdk_dbg3
++ *
++ *
++ * 1.2 How to use Debuggign strategy in driver development ?
++ * =========================================================
++ *
++ * 1. include debug-nomadik.h file in c code
++ * (path: include/asm-arm/arch/nomadik/debug-nomadik.h)
++ * 2. define NMDK_DEBUG to required debug level (this can be automated
++ * to pass build time debug levels -as done for keypad driver.
++ * See driver/input/keypad makefile)
++ * 3. define NMDK_DEBUG_PFX to a small string to identify debug message
++ * This is an optional setting, if you don't define NMDK_DEBUG_PFX,
++ * by default "Nomadik" will be selected.
++ * 4. define NMDK_DBG to desired Kerlen debug level
++ * This is an optional setting, if you don't define NMDK_DBG,
++ * by default KERN_DEBUG will be used
++ * This generally need to set to KERN_ERR to force debug messages to
++ * appear on the console
++ *
++ *
++ * 1.3 How to activate debug messages?
++ *====================================
++ *
++ * Debug messages can be activated during build time by passing desired
++ * debug level either hardcoding in source file or as a make parameter
++ *
++ * 1. Enabling Debug messages by passing additional parameter to make
++ * This is a recommended method of debug messages implimentation.
++ * this method give flexibility to enable/disable debug messages
++ * during build without modifying code
++ * (a) To enable this you need to updated driver make file with:-
++ * ex.
++ * ifdef <DRVNAME>_DEBUG
++ * CFLAGS += -<DRVNAME>_DEBUG=$(<DRVNAME>_DEBUG)
++ * endif
++ *
++ * (b) Same <DRVNAME>_DEBUG must be used to define NMDK_DEBUG as
++ * explained in (1.2.2)
++ * (c) Debug parameter must be passed to the make with desired debug
++ * level as explained in (1.1)
++ * ex. make <DRVNAME>_DEBUG=1
++ * (d) you can AND several debug levels togather to enable respective
++ * debug mesages
++ * (e) even you can pass additional parameters to enable debug messages
++ * of more than one module
++ * ex. make <DRV1>_DEBUG=1 <DRV2>_DEBUG=4 ...
++ *
++ * 2. Enabling Debug messages by hardcoding in source file
++ * This is simplest implimentation, just define NMDK_DEBUG to
++ * desired debug level and compile the code, the disadvantage of this
++ * method is, it does not offer flexibility and code with debug message
++ * may become part of your release if not taken care properly.
++ *
++ */
+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
+
-+#
-+# PHY device support
-+#
-+# CONFIG_PHYLIB is not set
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt
+@@ -0,0 +1,420 @@
++Filename: ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
++Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner: STMicroelectronics
++Purpose:
++ This Users Guide explains DMA implimentation and its usage
++ for client drivers on Nomadik platforms
++=============================================================================
+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+CONFIG_MII=m
-+CONFIG_SMC91X=m
-+# CONFIG_DM9000 is not set
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
++2. you are familier with Kernal DMA interface
++ (References: ./Documentation/DMA-API.txt)
+
-+#
-+# Ethernet (1000 Mbit)
-+#
++DMA Configuration:
++===================
++By default Nomadik DMA driver is configured to link staticlly with kernel.
++This DMA driver provides low level interface to the kernel DMA interface.
++To use DMA APIs, client driver should only include <asm/dma.h>
+
-+#
-+# Ethernet (10000 Mbit)
-+#
++Definations:
++============
++1. DMA Channel: The logical DMA channel can be used for a DMA transfer
++2. Pipe: the physical DMA chanel H/w that is used to a DMA transfer
++3. DMAC: Direct Memory Access Controller (Nomadik has two DMACs)
+
-+#
-+# Token Ring devices
-+#
++Brief Architecture:
++===================
++DMA dirver is registered as amba device and will be probed only if
++matches peripharal ID, the SOC specific data/function iterface is provided
++through platfrom_data pointer to allign driver design in sync with multiboard
++strategy.
++There are two DMA controllers having 8 pipes each, there could be number of
++dma channels which will use any one available pipe for dma transfer at run time
++Kernel DMA interface defines and controls the interface, whereas the h/w
++specific APIs are mapped through methods provided by upper layer (i,e.
++arch/arm/kernel/dma.c). The configuration, usage and features provided by this
++driver is explained below.
+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
++This Users guide explains-
++1. Support for Standard DMA APIs for Nomadik DMA usage
++2. Additional DMA APIs to facilitate effieient/flexible DMA usage
++3. DMA Channel configuration.
++ a) Mode of operation: Transfer type
++ b) Mode of operation: flow control
++ c) Mode of operation: Double Buffered Transfer
++ d) Mode of operation: Infinite DMA Transfer
++ e) Mode of operation: Infinite DMA Transfer
++ f) Mode of operation: Pipe reservation
++ g) Mode of operation: Channel Priority
++ h) Mode of operation: Queueing DMA transfer requests
++4. DMA Interrupt hanndling for callback functions.
++5. Scatter-gather Support
++6. /proc/dma interfce.
++7. HOWTO add new DMAable peripharal device support
+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+# CONFIG_SHAPER is not set
-+# CONFIG_NETCONSOLE is not set
-+# CONFIG_NETPOLL is not set
-+# CONFIG_NET_POLL_CONTROLLER is not set
++1. Support for Standard DMA APIs for Nomadik DMA usage
++======================================================
++Standard kernel DMA interface exports APIs out of which request_dma, enable_dma,
++disable_dma, free_dma, dma_channel_active, set_dma_sg, __set_dma_addr, set_dma_count,
++are supported for Nomadik DMA Usage.
++For any DMA transfer you need to follow a sequence-
++ a) request_dma : to request a DMA channel be to used for transfer,
++ in this request you need to pass configuration
++ b) request_irq : to register DMA callback function
++ c) __set_dma_srcaddr : to set src DMAble address (mapped to __set_dma_addr)
++ d) __set_dma_destaddr : to set dest DMAble address (mapped to set_dma_speed)
++ e) set_dma_count : to set transfer size in bytes
++ f) set_dma_mode : to set/ulter mode of operation (optional)
++ g) enable_dma : to start transfer
++ h) dma_channel_active : to know the status of scheduled transfer (optional)
++ i) disable dma : to stop transfer (optional)
++ j) free_irq : to free irq used for callback (optional)
++ k) free_dma : to free requested DMA channel
+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
++2. Additional DMA APIs for effieient/flexible DMA usage
++=======================================================
++Following additional APIs are provided for effieient/flexible DMA usage
++ a) request_available_dma
++ : This is a wrapper over request_dma,
++ this API will search, allocate and return available
++ free DMA channel.
++ b) suspend_DMA : to pause currently active DMA transfer
++ c) resume_DMA : to resume previously paused DMA transfer
+
-+#
-+# Input device support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_FF_MEMLESS is not set
++3. DMA Channel Configureation:
++==============================
++Durring request_dma system call you need to pass a pointer of pre-filled DMA
++Channel configuration structure nmdk_dma_info defined in asm/arch/dma.h
++i.e.-
++struct nmdk_dma_info {
++ u32 mode; /* Mode of operation(xfer type/flow cntrl etc)*/
++ char *srcdevtype; /* source device type configuration*/
++ char *destdevtype; /* desitnation device type configuration*/
++ u32 config; /* User programmable dmadev configuration*/
++};
+
-+#
-+# Userland interfaces
-+#
-+CONFIG_INPUT_MOUSEDEV=m
-+CONFIG_INPUT_MOUSEDEV_PSAUX=y
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_TSDEV is not set
-+CONFIG_INPUT_EVDEV=m
-+# CONFIG_INPUT_EVBUG is not set
++Each DMA channle has source DMA device and a destination DMA device, a DMA
++channel is a hardware that connects two DMAable devices for data transfer.
++So to have a successfull DMA transfer you need to configure all these three.
++Below picture gives some idea about it-
+
-+#
-+# Input Device Drivers
-+#
-+CONFIG_INPUT_KEYBOARD=y
-+# CONFIG_KEYBOARD_ATKBD is not set
-+# CONFIG_KEYBOARD_SUNKBD is not set
-+# CONFIG_KEYBOARD_LKKBD is not set
-+# CONFIG_KEYBOARD_XTKBD is not set
-+# CONFIG_KEYBOARD_NEWTON is not set
-+# CONFIG_KEYBOARD_STOWAWAY is not set
-+CONFIG_KEYPAD_NOMADIK=m
-+# CONFIG_INPUT_MOUSE is not set
-+# CONFIG_INPUT_JOYSTICK is not set
-+CONFIG_INPUT_TOUCHSCREEN=y
-+# CONFIG_TOUCHSCREEN_ADS7846 is not set
-+# CONFIG_TOUCHSCREEN_GUNZE is not set
-+# CONFIG_TOUCHSCREEN_ELO is not set
-+# CONFIG_TOUCHSCREEN_MTOUCH is not set
-+# CONFIG_TOUCHSCREEN_MK712 is not set
-+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-+# CONFIG_TOUCHSCREEN_UCB1400 is not set
-+CONFIG_TOUCHSCREEN_NOMADIK=m
-+# CONFIG_INPUT_MISC is not set
+
-+#
-+# Hardware I/O ports
-+#
-+# CONFIG_SERIO is not set
-+# CONFIG_GAMEPORT is not set
++ --------------------
++ srcdevtype, src_addr | | destdevtype, dest_addr
++ def dmadev config | | default dmadev configuration
++ | |
++ (Src DMA periph)------>| DMA Channel |--------> (Dest DMA peripharal)
++ | |
++ --------------------
++ (mode of operation)
++ (User configuration)
++ (Xfer Size in bytes)
+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_HW_CONSOLE=y
-+# CONFIG_VT_HW_CONSOLE_BINDING is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
++DMAable devices and their default configurations are SOC specific and declared
++in arch/arm/mach-nomadik/<SOC_NAME>_devices.c file (will be explained latter
++in this guide). Each DMAble device is identified by unique name, during
++configuration the src and dest dmadev names need to be specified.
+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_8250 is not set
++Transfer Size in bytes, src_addr and dest_addr not a part of configuration as
++they keeps changing and need to be provided before enable_dma request
+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+CONFIG_SERIAL_AMBA_PL011=y
-+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_LEGACY_PTYS=y
-+CONFIG_LEGACY_PTY_COUNT=256
++User programmable dmadev configuration: These are optional configuration on
++the top of default for the changable paramters (specially Brust size and
++transfer width). This will be exmpained latter in this guide
+
-+#
-+# IPMI
-+#
-+# CONFIG_IPMI_HANDLER is not set
++for ex, to configure a dma chnnel for memory to MSP peripharal DMA transfer
++the sructure should be filled as-
+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+CONFIG_HW_RANDOM=m
-+# CONFIG_NVRAM is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_RAW_DRIVER is not set
++ struct nmdk_dma_info test_dma_config =
++ {
++ .mode = MEM_TO_MEM,
++ .srcdevtype = "mem",
++ .destdevtype = "msp0rx",
++ .config = NULL,
++ };
+
-+#
-+# TPM devices
-+#
-+# CONFIG_TCG_TPM is not set
++Out of all configuration parameter "mode" is very important since it decides
++the mode of DMA channel operation, there are several features supported all
++are configurable through mode.
+
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+CONFIG_I2C_CHARDEV=y
++ a) Mode of operation: Transfer type
++ there are four basic modes of operation those are
++ MEM_TO_MEM, MEM_TO_PERIPH, PERIPH_TO_MEM, PERIPH_TO_PERIPH
++ you should program any one as per you need.
+
-+#
-+# I2C Algorithms
-+#
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
++ for ex. dma_info.mode=MEM_TO_PERIPH;
+
-+#
-+# I2C Hardware Bus support
-+#
-+CONFIG_I2C_NOMADIK=y
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_STUB is not set
-+# CONFIG_I2C_PCA_ISA is not set
++ b) Mode of operation: flow control
++ By default flow controller is DMA controller, if you want to program
++ flow controller as peripharal you can use the provided macros as
+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 is not set
-+# CONFIG_SENSORS_PCA9539 is not set
-+# CONFIG_SENSORS_PCF8591 is not set
-+# CONFIG_SENSORS_MAX6875 is not set
-+# CONFIG_I2C_DEBUG_CORE is not set
-+# CONFIG_I2C_DEBUG_ALGO is not set
-+# CONFIG_I2C_DEBUG_BUS is not set
-+# CONFIG_I2C_DEBUG_CHIP is not set
++ for ex. dma_info.mode=FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++ To mention the flow controller is DMA controller.
+
-+#
-+# SPI support
-+#
-+CONFIG_SPI=y
-+# CONFIG_SPI_DEBUG is not set
-+CONFIG_SPI_MASTER=y
++ for ex. dma_info.mode=FLOW_CNTRL_PERIPH(MEM_TO_PERIPH);
++ To mention the flow controller is peripharal controller.
+
-+#
-+# SPI Master Controller Drivers
-+#
-+# CONFIG_SPI_BITBANG is not set
-+CONFIG_NOMADIK_SPI=m
++ Flow controller device cannot be peripharal for MEM_TO_MEM transter
+
-+#
-+# SPI Protocol Masters
-+#
++ c) Mode of operation: Double Buffered Transfer
++ There are some peripharals like SAA(Smart Audio Accelerator) who
++ requires DMA transfers to be done in double buffer mode, in double
++ buffered mode of operation the current dma requested in divided in two,
++ equal sequential transfers before scheduling.
+
-+#
-+# Dallas's 1-wire bus
-+#
-+# CONFIG_W1 is not set
++ By default standard single buffered transfer mode is programmed,
++ to configure Double Buffered Transfer mode a macro DMA_DOUBLE_BUFFERED
++ should be ORed with other configuration parameters
+
-+#
-+# Hardware Monitoring support
-+#
-+CONFIG_HWMON=y
-+# CONFIG_HWMON_VID is not set
-+# CONFIG_SENSORS_ABITUGURU is not set
-+# CONFIG_SENSORS_ADM1021 is not set
-+# CONFIG_SENSORS_ADM1025 is not set
-+# CONFIG_SENSORS_ADM1026 is not set
-+# CONFIG_SENSORS_ADM1031 is not set
-+# CONFIG_SENSORS_ADM9240 is not set
-+# CONFIG_SENSORS_ASB100 is not set
-+# CONFIG_SENSORS_ATXP1 is not set
-+# CONFIG_SENSORS_DS1621 is not set
-+# CONFIG_SENSORS_F71805F is not set
-+# CONFIG_SENSORS_FSCHER is not set
-+# CONFIG_SENSORS_FSCPOS is not set
-+# CONFIG_SENSORS_GL518SM is not set
-+# CONFIG_SENSORS_GL520SM is not set
-+# CONFIG_SENSORS_IT87 is not set
-+# CONFIG_SENSORS_LM63 is not set
-+# CONFIG_SENSORS_LM70 is not set
-+# CONFIG_SENSORS_LM75 is not set
-+# CONFIG_SENSORS_LM77 is not set
-+# CONFIG_SENSORS_LM78 is not set
-+# CONFIG_SENSORS_LM80 is not set
-+# CONFIG_SENSORS_LM83 is not set
-+# CONFIG_SENSORS_LM85 is not set
-+# CONFIG_SENSORS_LM87 is not set
-+# CONFIG_SENSORS_LM90 is not set
-+# CONFIG_SENSORS_LM92 is not set
-+# CONFIG_SENSORS_MAX1619 is not set
-+# CONFIG_SENSORS_PC87360 is not set
-+# CONFIG_SENSORS_PC87427 is not set
-+# CONFIG_SENSORS_SMSC47M1 is not set
-+# CONFIG_SENSORS_SMSC47M192 is not set
-+# CONFIG_SENSORS_SMSC47B397 is not set
-+# CONFIG_SENSORS_VT1211 is not set
-+# CONFIG_SENSORS_W83781D is not set
-+# CONFIG_SENSORS_W83791D is not set
-+# CONFIG_SENSORS_W83792D is not set
-+# CONFIG_SENSORS_W83793 is not set
-+# CONFIG_SENSORS_W83L785TS is not set
-+# CONFIG_SENSORS_W83627HF is not set
-+# CONFIG_SENSORS_W83627EHF is not set
-+# CONFIG_HWMON_DEBUG_CHIP is not set
++ for ex. dma_info.mode=DMA_DOUBLE_BUFFERED |
++ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
+
-+#
-+# Misc devices
-+#
-+# CONFIG_TIFM_CORE is not set
++ d) Mode of operation: Infinite DMA Transfer
++ If you want to establish DMA transafer between two DMAble devices
++ infinitely without CPUs intervention, this means once transfer is
++ scheduled, it will reschedule it self at completion automatically.
+
-+#
-+# LED devices
-+#
-+# CONFIG_NEW_LEDS is not set
++ By default infinite DMA transfer is disabled,
++ to configure Infinite DMA Transfer mode a macro DMA_INFINITE_XFER
++ should be ORed with other configuration parameters
+
-+#
-+# LED drivers
-+#
++ for ex. dma_info.mode=DMA_INFINITE_XFER |
++ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
+
-+#
-+# LED Triggers
-+#
++ In Infinite DMA transfer mode, you will never receive completion
++ interrupt and callback interrupt handler cannot be executed
+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
++ e) Mode of operation: Pipe reservation
++ Reserving a pipe will dediate a pipe for a channel
++ By default pipe is not reserved at the time of configuration. when you
++ schedule a enable_dma request, system looks for the available pipe and
++ schedules a transfer on it. This adds more flexibility to system to
++ handle more channels on limited pipes. In case the all the pipes are
++ busy the request will be deffered,
++ if you want to avoid this behavior, i.e. whenever you request enable_dma
++ pipe must be available to execute it, then you can reserve a pipe during
++ configuration.
+
-+#
-+# Digital Video Broadcasting Devices
-+#
-+# CONFIG_DVB is not set
++ to reserve a pipe, a macro DMA_PIPE_RESERVED
++ should be ORed with other configuration parameters
+
-+#
-+# Graphics support
-+#
-+CONFIG_FIRMWARE_EDID=y
-+CONFIG_FB=y
-+CONFIG_FB_CFB_FILLRECT=y
-+CONFIG_FB_CFB_COPYAREA=y
-+CONFIG_FB_CFB_IMAGEBLIT=y
-+# CONFIG_FB_MACMODES is not set
-+# CONFIG_FB_BACKLIGHT is not set
-+CONFIG_FB_MODE_HELPERS=y
-+# CONFIG_FB_TILEBLITTING is not set
-+CONFIG_FB_ARMCLCD=y
-+# CONFIG_FB_S1D13XXX is not set
-+# CONFIG_FB_VIRTUAL is not set
++ for ex. dma_info.mode=DMA_PIPE_RESERVED |
++ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
+
-+#
-+# Console display driver support
-+#
-+# CONFIG_VGA_CONSOLE is not set
-+CONFIG_DUMMY_CONSOLE=y
-+CONFIG_FRAMEBUFFER_CONSOLE=y
-+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-+CONFIG_FONTS=y
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+# CONFIG_FONT_6x11 is not set
-+# CONFIG_FONT_7x14 is not set
-+# CONFIG_FONT_PEARL_8x8 is not set
-+# CONFIG_FONT_ACORN_8x8 is not set
-+# CONFIG_FONT_MINI_4x6 is not set
-+# CONFIG_FONT_SUN8x16 is not set
-+# CONFIG_FONT_SUN12x22 is not set
-+# CONFIG_FONT_10x18 is not set
++ g) Mode of operation: Channel Priority
++ At hardware level there are total 16 DMA pipes (i.e. 8 on each
++ DMAC) each having its priority (i.e. pipe 0 having highest and 7 with
++ lowest). but since the pipes are allocated dynamically you never know
++ which pipe will be assigned to which channel. To take care of this
++ issue driver has in-built channel priority policy manager
+
-+#
-+# Logo configuration
-+#
-+CONFIG_LOGO=y
-+CONFIG_LOGO_LINUX_MONO=y
-+CONFIG_LOGO_LINUX_VGA16=y
-+CONFIG_LOGO_LINUX_CLUT224=y
-+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++ Priority DMAC0 PIPES DMAC1 PIPES Policy
++ -----------------------------------------------------
++ Highest | 0 | | 1 | HIGH
++ . | 2 | | 3 | (0->15)
++ . -----------------------------------------------------
++ . | 4 | | 5 | NORMAL
++ . | 6 | | 7 | (4->15)
++ . -----------------------------------------------------
++ . | 8 | | 9 | LOW
++ . | 10 | | 11 | (8->15)
++ . -----------------------------------------------------
++ . | 12 | | 13 | UNDEFINED (fm 15->0)
++ Lowest | 14 | | 15 | For MEM-To MEM Xfer (15->12)
++ -----------------------------------------------------
+
-+#
-+# Sound
-+#
-+CONFIG_NOMADIK_ACODEC=m
-+CONFIG_NOMADIK_STW5094=y
-+# CONFIG_NOMADIK_STW5095 is not set
-+CONFIG_SOUND=m
++ Channel priority setup during configuration tells additional
++ information to the driver that the channel under request has a
++ particular priority. And the pipe allocation policy of a driver
++ allocates a pipe accordingly for a transfer under schedule.
+
-+#
-+# Advanced Linux Sound Architecture
-+#
-+CONFIG_SND=m
-+CONFIG_SND_TIMER=m
-+CONFIG_SND_PCM=m
-+# CONFIG_SND_SEQUENCER is not set
-+# CONFIG_SND_MIXER_OSS is not set
-+# CONFIG_SND_PCM_OSS is not set
-+# CONFIG_SND_DYNAMIC_MINORS is not set
-+CONFIG_SND_SUPPORT_OLD_API=y
-+CONFIG_SND_VERBOSE_PROCFS=y
-+# CONFIG_SND_VERBOSE_PRINTK is not set
-+# CONFIG_SND_DEBUG is not set
++ By default DMA_EXCH_PRIORITY_UNDEFINED is set for each channel, as
++ per policy the free and available pipe search will be started from
++ lowest to highest.
++ there are three other priorities HIGH, NORMAL and LOW which can be set
++ by ORing respective macro with other configuration parameters
+
-+#
-+# Generic devices
-+#
-+# CONFIG_SND_DUMMY is not set
-+# CONFIG_SND_MTPAV is not set
-+# CONFIG_SND_SERIAL_U16550 is not set
-+# CONFIG_SND_MPU401 is not set
++ for ex. dma_info.mode=DMA_EXCH_PRIORITY_HIGH |
++ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
+
-+#
-+# ALSA ARM devices
-+#
-+CONFIG_SND_NOMADIK_ALSA=m
-+# CONFIG_SND_ARMAACI is not set
++ Channel priority setup macros for configurations-
++ DMA_EXCH_PRIORITY_UNDEFINED
++ DMA_EXCH_PRIORITY_LOW
++ DMA_EXCH_PRIORITY_NORMAL
++ DMA_EXCH_PRIORITY_HIGH
+
-+#
-+# Open Sound System
-+#
-+# CONFIG_SOUND_PRIME is not set
++ h) Mode of operation: Queueing DMA transfer requests
++ In the standard kernel DMA interface channel queueing is not allowed
++ once enable_dma request is executed system discards all subsequent
++ enable_dma request untill DMA finishes first scheduled request.
++ Nomadik DMA driver provides you flexibility to enable and use this
++ feature if required. Enabling this feature will accept all subsequent
++ enable_dma requests and queue them in a pipe, as system finishes
++ current transfer, next pre-scheduled transfer in a queue will be
++ executed, thus all enable_dma requests can be processed.
+
-+#
-+# HID Devices
-+#
-+CONFIG_HID=y
++ This feature can be enabled by ORing a macro DMA_QUEUE_ENABLED with
++ other configuration parameters
+
-+#
-+# USB support
-+#
-+CONFIG_USB_ARCH_HAS_HCD=y
-+# CONFIG_USB_ARCH_HAS_OHCI is not set
-+# CONFIG_USB_ARCH_HAS_EHCI is not set
-+# CONFIG_USB is not set
++ for ex. dma_info.mode=DMA_QUEUE_ENABLED |
++ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
+
-+#
-+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-+#
++4. DMA Interrupt hanndling for callback functions.
++======================================================
++When you schedule a DMA transfer, there should be a mechanism by which you know
++the transfer is finished sucessfully. In Nomadik DMA transfer a terminal
++count interrupt will be generated at the end of sucessfull transfer which can
++be requested and processed like any other standard interrupt.
+
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
++There are S/w decoded IRQs associated with all DMA channels.
++the macro IRQNO_FOR_DMACH(dmach) is provided to find irq for a DMA channel and
++the macro DMACH_FOR_IRQNO(irq) can be used to find DMA channel for irq number
+
-+#
-+# MMC/SD Card support
-+#
-+CONFIG_MMC=m
-+# CONFIG_MMC_DEBUG is not set
-+CONFIG_MMC_BLOCK=m
-+# CONFIG_MMC_ARMMMCI is not set
-+# CONFIG_MMC_WBSD is not set
-+# CONFIG_MMC_TIFM_SD is not set
-+CONFIG_MMC_NOMADIK=m
-+CONFIG_NOMADIK_MMC_DMA=y
-+# CONFIG_NOMADIK_MMC_POLL is not set
-+# CONFIG_NOMADIK_MMC_INTR is not set
++The DMA callback functions can be invoked as interrupt handler and requested
++through standard system calls i.e request_irq and free_irq.
+
-+#
-+# Real Time Clock
-+#
-+CONFIG_RTC_LIB=y
-+# CONFIG_RTC_CLASS is not set
++It is recommented to use your own tasklets to do deffered processing
++since it may block other DMA interuppts being processed in time.
+
-+#
-+# File systems
-+#
-+CONFIG_EXT2_FS=y
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XIP is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_EXT4DEV_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_JFS_FS is not set
-+# CONFIG_FS_POSIX_ACL is not set
-+# CONFIG_XFS_FS is not set
-+# CONFIG_GFS2_FS is not set
-+# CONFIG_OCFS2_FS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_FUSE_FS is not set
++Below system messages indicates that irqno 188 to 191 are DMA interrupts
++root@NDK10_A0:/home/prafulla/alsa# cat /proc/interrupts
++ CPU0
++ 4: 12077:PL02 - Nomadik Timer Tick
++ 10: 0 - rtc
++ 11: 0 - ssp
++ 17: 581:PL08 - uart-pl011
++ 19: 6:PL10 - msp
++ 20: 33 - i2c0
++ 21: 296 - i2c1
++ 22: 81:PL02 - NMDK_MMC (data)
++ 26: 1 - SAA0
++ 27: 0 - SAA1
++113: 0 - mmc_detect
++168: 19176:PL08 - eth0
++188: 46 dummy dmaclbk-sdmmc->mem
++189: 0 dummy <NULL>
++190: 10462 dummy dmaclbk-msp0rx->mem
++191: 10437 dummy dmaclbk-mem->msp0tx
++Err: 0
+
-+#
-+# CD-ROM/DVD Filesystems
-+#
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_UDF_FS is not set
++5. Scatter-gather Support
++======================================================
++The Nomadik DMA driver supprts scatter-gather transfer for MEM_TO_PERIPH and
++PERIPH_TO_MEM type of data transfer. to use scatter gather suport following
++sequence must be executed.
++ a) request_dma, request_irq
++ b) get the *sg and sg_len form the upper layers
++ c) execute dma_map_sg with above information
++ d) set peripharal DMA address (__set_dma_srcaddr / __set_dma_srcaddr)
++ e) set memory DMA address using set_dma_sg API with sg information
++ f) set_dma_count for transfer size
++ g) execute enable_dma
++ h) wait for transfer complete event through callback
++ i) unmap sg list using dma_unmap_sg
++ j) free_dma
+
-+#
-+# DOS/FAT/NT Filesystems
-+#
-+CONFIG_FAT_FS=m
-+# CONFIG_MSDOS_FS is not set
-+CONFIG_VFAT_FS=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="cp437"
-+# CONFIG_NTFS_FS is not set
++6. /proc/dma interfce.
++======================================================
++/proc/dma entry is created to show the information of allocated DMA resources
++executing cat /proc/dma will list the allocation of all used DMA channles
+
-+#
-+# Pseudo filesystems
-+#
-+CONFIG_PROC_FS=y
-+CONFIG_PROC_SYSCTL=y
-+CONFIG_SYSFS=y
-+CONFIG_TMPFS=y
-+# CONFIG_TMPFS_POSIX_ACL is not set
-+# CONFIG_HUGETLB_PAGE is not set
-+CONFIG_RAMFS=y
-+# CONFIG_CONFIGFS_FS is not set
++for ex-
++root@NDK10_A0:/home/prafulla/alsa# cat /proc/dma
++ 0: DMACH: sdmmc->mem
++ 1: DMACH: mem->sdmmc
++ 2: DMACH: msp0rx->mem
++ 3: DMACH: mem->msp0tx
+
-+#
-+# Miscellaneous filesystems
-+#
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_HFSPLUS_FS is not set
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+CONFIG_JFFS2_FS_WRITEBUFFER=y
-+# CONFIG_JFFS2_SUMMARY is not set
-+# CONFIG_JFFS2_FS_XATTR is not set
-+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-+CONFIG_JFFS2_ZLIB=y
-+CONFIG_JFFS2_RTIME=y
-+# CONFIG_JFFS2_RUBIN is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
++7. HOWTO add new DMA peripharal device support
++======================================================
++As per multiboard strategy
++(ref : ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt)
++for each supported SOC there is an arch/arm/mach-nomadik/<SOC>_devices.c
++In this file there is data structure "dmadev_default_config_tbl"
++Add a new entry for the table for new DMA peripharal device
++(refer Architecture.DMA Support Chapter fo SOC specification)
+
-+#
-+# Network File Systems
-+#
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+# CONFIG_NFS_V3_ACL is not set
-+CONFIG_NFS_V4=y
-+# CONFIG_NFS_DIRECTIO is not set
-+# CONFIG_NFSD is not set
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=y
-+CONFIG_SUNRPC_GSS=y
-+CONFIG_RPCSEC_GSS_KRB5=y
-+# CONFIG_RPCSEC_GSS_SPKM3 is not set
-+# CONFIG_SMB_FS is not set
-+# CONFIG_CIFS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_CODA_FS is not set
-+# CONFIG_AFS_FS is not set
-+# CONFIG_9P_FS is not set
++for ex-
++ {.id = "sdmmc",
++ .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD |
++ DMA_BSIZE_8 | DMA_REQUEST_LINE(21) |
++ DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE |
++ DMA_DEV_DMAC1_CANBE_USED ),},
+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
++ explaination:
++ id: This is the unique identification string will be used in
++ configuration as srcdevtype or destdevtype.
++ config: This should be ORed value of following selection
++ a) DMA_AHB_M0 : to select AHB master 0 for this device
++ or
++ DMA_AHB_M1 : to select AHB master 1 for this device
+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS=y
-+CONFIG_NLS_DEFAULT="cp437"
-+CONFIG_NLS_CODEPAGE_437=m
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+# CONFIG_NLS_CODEPAGE_850 is not set
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+# CONFIG_NLS_ASCII is not set
-+# CONFIG_NLS_ISO8859_1 is not set
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
++ b) DMA_ADR_INC : to indicate DMA address is incremented after
++ each transfer (memory, buffer case)
++ or
++ DMA_ADR_NOINC : to indicate DMA address is not incremented
++ after each transfer (fifo case)
+
-+#
-+# Distributed Lock Manager
-+#
-+# CONFIG_DLM is not set
++ c) DMA_WIDTH_WORD : to select word(32bits) as transfer width
++ or
++ DMA_WIDTH_HALFWORD: to select halfword(16bits) as transfer width
++ or
++ DMA_WIDTH_BYTE : to select byte(8bits) as transfer width
+
-+#
-+# Profiling support
-+#
-+# CONFIG_PROFILING is not set
++ d) DMA_BSIZE_1 : to indicate 1 byte makes one DMA brust
++ or
++ DMA_BSIZE_4 : to indicate 4 bytes makes one DMA brust
++ or
++ DMA_BSIZE_8 : to indicate 8 bytes makes one DMA brust
++ or
++ DMA_BSIZE_16 : to indicate 16 bytes makes one DMA brust
++ or
++ DMA_BSIZE_32 : to indicate 32 bytes makes one DMA brust
++ or
++ DMA_BSIZE_64 : to indicate 64 bytes makes one DMA brust
++ or
++ DMA_BSIZE_128 : to indicate 128 bytes makes one DMA brust
++ or
++ DMA_BSIZE_256 : to indicate 256 bytes makes one DMA brust
+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_MUST_CHECK=y
-+CONFIG_MAGIC_SYSRQ=y
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+CONFIG_DEBUG_KERNEL=y
-+CONFIG_LOG_BUF_SHIFT=14
-+CONFIG_DETECT_SOFTLOCKUP=y
-+# CONFIG_SCHEDSTATS is not set
-+# CONFIG_DEBUG_SLAB is not set
-+CONFIG_DEBUG_PREEMPT=y
-+# CONFIG_DEBUG_RT_MUTEXES is not set
-+# CONFIG_RT_MUTEX_TESTER is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+CONFIG_DEBUG_MUTEXES=y
-+# CONFIG_DEBUG_RWSEMS is not set
-+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-+# CONFIG_DEBUG_KOBJECT is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_DEBUG_VM is not set
-+# CONFIG_DEBUG_LIST is not set
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_FORCED_INLINING is not set
-+# CONFIG_RCU_TORTURE_TEST is not set
-+# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
-+# CONFIG_KGDB is not set
-+# CONFIG_DEBUG_USER is not set
-+# CONFIG_DEBUG_ERRORS is not set
-+# CONFIG_DEBUG_LL is not set
++ e) DMA_REQUEST_LINE(x) : program peripharal request line number
++ (x less than 32)
+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+# CONFIG_SECURITY is not set
++ f) DMA_DEV_BSIZE_CONFIGURABLE: to indicate the burst size can be
++ probrammed by user
++ or
++ DMA_DEV_BSIZE_NOT_CONFIGURABLE: to indicate the burst size can
++ not be probrammed by user
++ g) DMA_DEV_DWIDTH_CONFIGURABLE: to indicate the transfer width can
++ be probrammed by user
++ or
++ DMA_DEV_DWIDTH_NOT_CONFIGURABLE: to indicate the transfer width
++ can not be probrammed by user
+
-+#
-+# Cryptographic options
-+#
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+CONFIG_CRYPTO_MANAGER=y
-+# CONFIG_CRYPTO_HMAC is not set
-+# CONFIG_CRYPTO_XCBC is not set
-+# CONFIG_CRYPTO_NULL is not set
-+# CONFIG_CRYPTO_MD4 is not set
-+CONFIG_CRYPTO_MD5=y
-+# CONFIG_CRYPTO_SHA1 is not set
-+# CONFIG_CRYPTO_SHA256 is not set
-+# CONFIG_CRYPTO_SHA512 is not set
-+# CONFIG_CRYPTO_WP512 is not set
-+# CONFIG_CRYPTO_TGR192 is not set
-+# CONFIG_CRYPTO_GF128MUL is not set
-+CONFIG_CRYPTO_ECB=m
-+CONFIG_CRYPTO_CBC=y
-+# CONFIG_CRYPTO_LRW is not set
-+CONFIG_CRYPTO_DES=y
-+# CONFIG_CRYPTO_BLOWFISH is not set
-+# CONFIG_CRYPTO_TWOFISH is not set
-+# CONFIG_CRYPTO_SERPENT is not set
-+# CONFIG_CRYPTO_AES is not set
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+# CONFIG_CRYPTO_ARC4 is not set
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+# CONFIG_CRYPTO_MICHAEL_MIC is not set
-+# CONFIG_CRYPTO_CRC32C is not set
-+# CONFIG_CRYPTO_TEST is not set
++ h) DMA_DEV_DMAC1_CANBE_USED: to indicate DMA controller1 can be
++ used for the transfer
++ or
++ DMA_DEV_DMAC0_CANBE_USED: to indicate DMA controller0 can be
++ used for the transfer
++ or
++ DMA_DEV_BOTH_DMACS_CANBE_USED: to indicate both DMA controllers
++ 0 and 1 can be used for the transfer
+
-+#
-+# Hardware crypto devices
-+#
++8. System Limitations and Solutions:
++=====================================
++1. MAX_DMA_CHANNELS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
++ that defiens max no. of dma channels that can be used simultenously. if in
++ complex system scenario these channels are insuffienent, you may increase
++ this number as per your needs.
++2. MAX_DMA_LLIS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
++ that defiens max no. of LLIs used internally by dma driver. lli pool is
++ internally maitained by driver and aquired whenver there is a enable_dma
++ request and freed at each dma transfer completion. In a dynamic system
++ usage a run time message "unable to find free lli.. rechecking..." can be
++ observed, if such case you may increase the defined value for this macro,
++ Assiging very large value eats free DMAble memory.
+
-+#
-+# Library routines
-+#
-+CONFIG_BITREVERSE=y
-+# CONFIG_CRC_CCITT is not set
-+# CONFIG_CRC16 is not set
-+CONFIG_CRC32=y
-+CONFIG_LIBCRC32C=m
-+CONFIG_ZLIB_INFLATE=y
-+CONFIG_ZLIB_DEFLATE=y
-+CONFIG_PLIST=y
-+CONFIG_IOMAP_COPY=y
-diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk15b06_defconfig
---- linux-2.6.20/arch/arm/configs/ndk15b06_defconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/configs/ndk15b06_defconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1221 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.20
-+# Thu Aug 16 17:22:36 2007
-+#
-+CONFIG_ARM=y
-+# CONFIG_GENERIC_TIME is not set
-+CONFIG_MMU=y
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++==============================================================================
+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_LOCK_KERNEL=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
+
-+#
-+# General setup
-+#
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_IPC_NS is not set
-+# CONFIG_POSIX_MQUEUE is not set
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+# CONFIG_TASKSTATS is not set
-+# CONFIG_UTS_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_INITRAMFS_SOURCE=""
-+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-+CONFIG_SYSCTL=y
-+CONFIG_EMBEDDED=y
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_ALL is not set
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_EPOLL=y
-+CONFIG_SHMEM=y
-+CONFIG_SLAB=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+# CONFIG_SLOB is not set
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt
+@@ -0,0 +1,53 @@
++Filename: ./Documentation/arm/STM-Nomadik/faqs.txt
++Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner: STMicroelectronics
++Purpose:
++ This documents describes frequesnty occuring problems and
++ their brief solutions while using Nomadik-BSP
++=============================================================================
+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+# CONFIG_MODULE_FORCE_UNLOAD is not set
-+# CONFIG_MODVERSIONS is not set
-+# CONFIG_MODULE_SRCVERSION_ALL is not set
-+# CONFIG_KMOD is not set
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
+
-+#
++F.A.Qs
++======
++Q: I am not getting console on CLCD even though CLCD is enabled
++A: check your command line arguments, there should not be any console related
++ configuration, in this case by default console will be configured to CLCD.
++ In this case system will seek console input from standard input device.
++
++Q: NFS boot is giving messages "server not responding" very frequently
++A: This may be due to network congestion, try NFS boot using "tcp" option
++ (Ex. root=/dev/nfs nfsroot=<server_ipadr>:<mount_point_path>,tcp
++ ip=<host_ipadr>:<server_ipadr>:<gateway_ipard>:255.255.255.0:<hostname>::
++ console=ttyAMA1 mem=64M init=linuxrc)
++
++Q. How to enable/Disable cursor on CLCD panel?
++A. Create a dummy node "mknod /dev/dummy c 4 0 ".
++ execute a command "echo -e "\033[?1c" > /dev/dummy" to disable the cursor
++ and "echo -e "\033[?0c" > /dev/dummy" to enable the cursor
++ You can also use the "setterm" program to control this and other aspects of
++ the console. "setterm -cursor off > /dev/tty0" will do what you want.
++ "man setterm" will give a vast list of stuff.
++ There is more here:
++ http://linux.bri.st.com/docs/manual/distribution/distribution_guide10.php
++
++Q. How to disable CLCD screen blanking
++A. Create a dummy node "mknod /dev/dummy c 4 0 ".
++ Execute a command "echo -e "\033[9;0]" > /dev/dummy", this will set
++ screen blanking interval to 0 and will not blank the screen at all.
++
++Q. Generally when the kernel is up and running, CLCD is active but after some
++ time screen gets blanked, How to unblank the already blanked CLCD screen ?
++A. Create a dummy node "mknod /dev/dummy c 4 0 ".
++ Execute a command "echo -e "\033[13]" > /dev/dummy", this will activate
++ CLCD screen.
++
++Q. How to enable L2 Cache for Nomadik SOCs
++A. Switch to kernel source path, execute "make menuconfig"
++ Enable option "Enable L2 Cache controller" at location "x -> System Type"
++ L2CC is not available on STn8810 SOC versions
++
++==============================================================================
++
++
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt
+@@ -0,0 +1,140 @@
++Filename: ./Documentation/arm/STM-Nomadik/gpio_user_guide.txt
++Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner: STMicroelectronics
++Purpose:
++ This Users Guide explains GPIO implimentation and its usage
++ from other drivers for Nomadik platforms
++=============================================================================
++
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
++
++GPIO Configuration:
++===================
++By default GPIO driver is configured to link staticlly with kernel becasue
++it is tightly coupled with irq.c. GPIO is necessary for Nomadik architecture
++
++Brief Architecture:
++GPIO dirver is registered as amba device and will be probed only if
++matches peripharal ID, the SOC specific data and function iterface is provided
++through platfrom_data pointer to allign driver code in sync with multiboard
++strategy.
++
++GPIO driver mainly provides two kinds of functionality
++1. GPIO Interrupt hanndling and control.
++2. Exported GPIO APIs
++ 2.1 Usage of GPIO pins/block for read write APIs
++ 2.2 Configuration for Alternate functions APIs
++
++1. GPIO Interrupt hanndling and control:-
++==============================================
++VIC generates a common interrupt for all 32 pins in a block, there are such
++three to four blocks in a SOC, Each GPIO interrupt can be considered as
++standard IRQ and can be processed through generic system call (please refer
++irq_usrguide.txt). Further GPIO interrupts are softdecoded hence canot be
++programmed as priority interrupts individually,
++
++2. Exported GPIO APIs
++=====================
++All exported GPIOs are protected against call before initialization. This
++means if the GPIO driver cannot be probled due to any reasons and you try to
++use GPIO exported APIs, and error will be returned.
++APIS nomadik_gpio_readpin and nomadik_gpio_readblock are not protected against
++interrupt configuration becasue reading a GPIO does not harm its usage from
++other context. Where as all other APIS are protected against interrupt
++cnfiguration. This means if the interrupt is already requested on a GPIO pin
++the same pin cannot be configured untill you free that interrupt.
++
++2.1 Usage of GPIO pins/block for read write APIs
++================================================
++ a) nomadik_gpio_setpinconfig:
++ Individual pin can be configured for desired operation.
++ for ex.
++ mmc_pin.dev_name = "test";
++ mmc_pin.mode = GPIO_MODE_SOFTWARE;
++ mmc_pin.direction = GPIO_DIR_OUTPUT;
++ mmc_pin.debounce = GPIO_DEBOUNCE_ENABLE;
++ mmc_pin.debounce_time = GPIO_DEBOUNCE_TIME_60_MICROSEC;
++ ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++
++ The above code will configure GPIO_PIN_75 in GPIO mode used as output
++ pin, enabled debouncing logic and set debounce time to 60 miroseconds.
++ debounce logic will be enabled if supported by the SOC version.
++ dev_name is a client device name to which the GPIO will be allocated.
++
++ b) nomadik_gpio_resetpinconfig:
++ sets the particular pin to its reset state.
++
++ c) nomadik_gpio_writepin;
++ write HIGN or LOW value on specified pin
++
++ d) nomadik_gpio_readpin;
++ reads HIGN or LOW value from specified pin
++
++ e) nomadik_gpio_readblock;
++ write multiple bits on specifed group of GPIOs
++ ex.
++ err = nomadik_gpio_writeblock(GPIO_BLOCK_32_BITS_64_TO_95,
++ , 0x0000aa00, 0x0000fc00);
++
++ The above code writes HIGH on GPIO_PIN_74, LOW on GPIO_PIN_75,
++ HIGH on GPIO_PIN_76, LOW on GPIO_PIN_77, and HIGN on GPIO_PIN_78
++
++ f) nomadik_gpio_writeblock;
++ reads multiple bits on specifed group of GPIOs
++
++2.2 Configuration for Alternate functions APIs
++================================================
++ a) nomadik_gpio_altfuncenable:
++ Sets the group of GPIOs dedicated for spefic alternate mode of
++ operation.
++
++ for ex.
++ retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
++
++ The above code configures GPIOs 62 abd 63 (in case of stn8810) for
++ altfun_A, the detailed information which pins to be configured in which
++ mode for specified gpio_alt_function value(GPIO_ALT_I2C_0) is decided by
++ the gpio_altfun_tbl[] declared in <SOC>_devices.c. It has table entries
++ whcih controls altfun configuration.
++
++ for example entry in table
++ {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type =
++ GPIO_ALTF_A,},
++ states that- for gpio_alt_function value GPIO_ALT_I2C_0, from gpio pins 62
++ to 63 needs to be configured for alternate function A. cont=0 specifies that
++ there are no further pins to be configured for GPIO_ALT_I2C_0.
++
++ example for cont=1
++ {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type =
++ GPIO_ALTF_A,},
++ {.altfun = GPIO_ALT_SD_CARD,.start = 82,.end = 87,.cont = 1,.type =
++ GPIO_ALTF_A,},
++ {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type =
++ GPIO_ALTF_A,},
++
++ In the above example cont=1 in first and second declaration states that there
++ are additional entries in sequence to configure pins (82 to 87) and (14 to 16)
++ in altfun A mode for the same gpio_alt_function value GPIO_ALT_MM_CARD
++
++ b) nomadik_gpio_altfuncdisable:
++ This API reconfigures the group of GPIOs dedicated for specific
++ alternate mode of operation in to GPIO mode.
++
++Secured GPIO Access:
++===================
++To prevent GPIO resources getting used/altered by unauthorised way, a method
++is provided to give secured control. When gpio is requested by setpinconfig,
++you need to specify dev_name, GPIO driver records the information that the
++particular pin is alloocated the client named "dev_name", while doing
++resetpinconfig the same dev_id must be passed.
++Simillarly the same should be followed while requesting enabling/disabling altfunction.
++When the GPIO is requested for interrupt, the specified devname will be
++configured as client name.
++
++/proc/gpio interface:
++====================
++/proc/gpio entry is created to show the information of allocated GPIO resources
++
++=======================================================================================
++
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt
+@@ -0,0 +1,171 @@
++Filename: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
++Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner: STMicroelectronics
++Created: 9th June 2007
++
++Purpose:
++This Users Guide explains interrupts implimentation and its usage from other
++client drivers for Nomadik platforms
++
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
++
++Generic:
++========
++All the available interrupts can be used in through standard system calls
++To use nomadik interrupts, include <linux/interrupt.h> ONLY in your code
++Interrupt numbers generic to all Nomadik cuts are defined in irqs.h
++Interrupt numbers specific to Nomadik cut is defined in <soc>_devices.h
++(refer HOWTO-add_newboard.txt for more information)
++
++IRQ Description:
++================
++for stn8810 chip:
++ IRQ0 to IRQ31 : IRQ lines provided by the VIC for different
++ on-chip peripharals.
++ IRQ32 to IRQ127 : IRQ lines for GPIO interrupts
++
++for stn8815 chip:
++ IRQ0 to IRQ63 : IRQ lines provided by the VIC for different
++ on-chip peripharals.
++ IRQ64 to IRQ191 : IRQ lines for GPIO interrupts
++
++Specific:
++========
++1. Vectored Interrupt Controller (VIC) Interrupt Priority configuration:-
++========================================================================
++Generally whenever there is IRQ request to the VIC it will be processed
++immediately, if two or more IRQs active at a time then first in a sequence
++(i.e lower in number) will be processed first (this depends how you decode
++irqnr in entry-macro.S).
++
++Vectored interrupt processing hardware on Nomadik SOC is used to detect,
++process and service the interrupts in prioritized manner.
++This provides faster interrupt processing for comples decision.
++This adds more flexibility to the system and to the driver developers to
++take complex decision making about which interrupt to be proceesed first
++when more than one IRQ goes active at a time.
++
++also while processing priority interrupt all lower priority interrupts will
++be disabled by hardware whereas all higher priority interrupts will be active.
++This adds a benefit to use SA_IRQPRIORITY_x over SA_INTERRUPT becasue
++SA_INTERRUPT disables all interrupt while processign it.
++
++Any 15 (maximum) IRQs lines of VIC can be programmed for priority,
++GPIO_IRQs cannot be programmed for priority since the are softdecoded.
++
++How to program a interrupt for desired priority?
++================================================
++this can be done in two ways
++a. using request_irq
++ for ex.
++ err = request_irq(IRQ_UART1, test_inthandle, SA_IRQPRIORITY_4,
++ "test", test_data);
++
++ will request IRQ with interrupt priority level 4
++
++b) using set_irq_type
++ This call can be used any time after requesting a interrupt to
++ to enable/disable/change priority level for specific IRQ line
++
++ For ex.
++ set_irq_type(IRQ_UART1, SA_IRQPRIORITY_10);
++
++ will enable priority level for pre-requested IRQ
++ if IRQ was requested with different priority level earlier,
++ this call will change it to specified level
++
++How to disable interrupt priority for a IRQ?
++===========================================
++a) using set_irq_type api
++ This call can be used any time after requesting a interrupt to
++ to enable/disable/change priority level for specific IRQ line
++
++ For ex.
++ set_irq_type(IRQ_UART1, SA_IRQPRIORITY_DISABLE);
++
++ will disable priority level for pre-requested IRQ and will configure
++ if as normal IRQ
++
++How to know which IRQs are programmed for priority?
++===================================================
++executing cat /proc/interrupts interface will display all interrupt information
++if any IRQ is programmed with some priority then it will reflect as-
++
++# cat /proc/interrupts
++ CPU0
++ 4: 143193 Nomadik Timer Tick
++ 10: 0 rtc
++ 11: 0 ssp
++ 13: 1 dma1
++ 15: 0 dma0
++ 17: 745 uart-pl011
++ 20: 0 i2c0
++ 21: 4 i2c1
++ 22: 132 NMDK_MMC (data)
++ 30: 0:PL07 msp1
++ 31: 0 msp2
++ 72: 122 nmdk-kp
++ 77: 433 eth0
++ 79: 5175 nmdk-tp
++ 81: 32 mmc_detect
++Err: 0
++#
++
++Above message indicates that IRQ30 for msp1 is programmed as priority interrupt
++with level 7.
++
++2. GPIO Interrupt hanndling and control:-
++==============================================
++GPIO Interrupt control is handled through standard system calls. The macros
++(IRQNO_GPIO(x) and GPIO_PIN_FOR_IRQ(x)) are provided to find out interrupt
++number associated with GPIO and vice-versa.
++Following system calls are suported for GPIO interrupt control:-
++a) request_irq/ free_irq:
++ works in a standard way to request and free GPIO interrupt.
++ When request_irq is invoked for GPIO, it first configures GPIO pin
++ for input operation with debounce disable (if supported). Then it sets
++ interrupt type for falling edge detection by default if not specified
++ in interrupt_flags. You can set type of interrupt during request by
++ passing required SA_TTRIGGER_ flags. GPIO interrupt type will be set
++ during request_irq call if the requested interrupt is NOT shared.
++
++ for ex.
++ err = request_irq(IRQNO_GPIO(x), test_inthandle, SA_TRIGGER_RISING,
++ "test", test_data);
++
++ will request rising edge interrupt for GPIO x
++
++b) enable_irq/disable_irq:
++ These are standard system calls can be used to enable or disable GPIO
++ irqs whenever required.
++
++ for ex.
++ enable_irq(IRQNO_GPIO(x));
++
++ will enable interrupt for GPIO x
++
++c) set_irq_type:
++ By defult interrupt is requested as falling edge through request_irq call.
++ If you want to use other type of interrupt detection, this call can be used.
++ This call will be necessary to configure shared GPIO interrupt
++
++ For ex.
++ set_irq_type(IRQNO_GPIO(x), SA_TRIGGER_LOW);
++ sets irq type as low level detection
++
++ set_irq_type(IRQNO_GPIO(x), (SA_TRIGGER_RISING|SA_TRIGGER_FALLING);
++ sets irq type for both edges detection
++
++ Please note that set_irq_type overwites previous irq_type, hence the GPIO
++ interrupt behaviour depends upon where you call this API.
++
++ for ex. if you set_irq_type first and then requested interrupt, the
++ request_irq will overwrite the previously set irq type and vice versa.
++
++d) enable_irq_wake/disable_irq_wake:
++ the frame work is provided to handle these call for GPIO interrupt to
++ enable/disable wakup event generation to the power management unit.
++
++===============================================================================
++
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt
+@@ -0,0 +1,122 @@
++
++ * 1 Nomadik Power Management Strategy
++ * ==========================================
++ * Power in nomadik can be saved by following features
++ * 1. Enable idle tick suppression or dynamic tick
++ * 2. Frequency scaling
++ * 3. Voltage scaling
++ * 4. Take system into soft sleep
++ * 5. Take system into deep sleep
++ * 6. Taking individual device (eg. CLCD) into suspend state
++ *
++ *
++ * 1.1 How to Enable idle tick suppression or dynamic tick
++ * =========================================================
++ *
++ * 1. Select CONFIG_NO_IDLE_HZ in kernel features in kernel configuration
++ * 2. To enable dynamic tick
++ * echo -n 1 > /sys/devices/system/timer/timer0/dyn_tick
++ * 3. Dynamic tick can be disabled by
++ * echo -n 0 > /sys/devices/system/timer/timer0/dyn_tick
++ * 4. In idle thread, arm put itself in WFI, hence power is saved. By using
++ * dynamic tick we can put ARM in WFI for longer duration
++ *
++ * 1.2 Scaling frequencies
++ *====================================
++ * 1. Select CONFIG_CPU_FREQ & CONFIG_CPU_FREQ_NOMADIK in kernel configuration
++ * during compilation
++ * 2. Check current frequency (In Khz) by
++ * cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
++ * 3. Change system freq by
++ * echo -n <freq in khz > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
++ * If entered freq is not supported in system then next higher valid
++ * frequency is set
++ * 4. For frequencies which require voltage change, new voltage will be
++ * reflected. It can be checked by voltage sysfs file
++ * 5. If mapping for frequency and voltage is changed then change is required
++ * in arch/arm/mach-nomadik/power.c
++ * 6. If different SDRAM parameters are to be changed then change is required
++ * in arch/arm/mach-nomadik/power.c
++ * 7. If frequencies are to be altered then change is required in arch/arm/mach-nomadik/power.c
++ *
++ *
++ * 1.3 Scaling Voltage
++ *====================================
++ * 1. To enable voltage scaling either CONFIG_CPU_FREQ or CONFIG_PM_NOMADIK
++ * must be selected in configuration
++ * 2. Current voltage can be checked by
++ * cat /sys/nomadik/current_voltage
++ * VOLTAGE will be shown in milli volt
++ * 3. To change in current voltage without changing frequency use
++ * echo < voltage in milli volt > > current_voltage
++ * However directly changing voltage without frequency is not recommended
++ * but can be used for performance/testing purpose.
++ * 4. If voltages are to be altered then change is required in arch/arm/mach-nomadik/power.c
++ *
++ *
++ * 1.4 Taking system into soft sleep
++ *====================================
++ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
++ * 2. Change required sleep type to softsleep by
++ * echo -n softsleep > /sys/nomadik/sleep_type
++ * 3. To take system into sleep use
++ * echo -n mem > /sys/power/state
++ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
++ * 5. To specify rtc wakeup duration ( sleeping time )
++ echo -n <sleep duration in seconds > >sleep_duration
++ Default sleep duratioon is 15 seconds
++ * 6. To take system directly into soft sleep without linux power management
++ * framework use
++ * echo 1 > /sys/nomadik/softsleep_enable
++ * This is to be used when we are sure that no driver is active i.e.
++ * driver need not be be suspended. This interface can save transition
++ * time but is not recommended. It can be used for testing purpose.
++ *
++ *
++ * 1.5 Taking system into deep sleep
++ *====================================
++ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
++ * 2. Change required sleep type to deepsleep by
++ * echo -n deepsleep > /sys/nomadik/sleep_type
++ * 3. To take system into sleep use
++ * echo -n mem > /sys/power/state
++ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
++ * 5. To specify rtc wakeup duration ( sleeping time )
++ * echo -n <sleep duration in seconds > >sleep_duration
++ * Default sleep duration is 15 seconds
++ *
++ * 1.6 Taking Individual device into suspend/resume state
++ *=======================================================
++ * 1. Individual device can be taken into suspended state by writing into sysfs
++ * file. Similiarly device can be resumed back
++ * 2. For example to take CLCD into suspend state use
++ echo -n 2 > /sys/devices/mb:c0/power/state
++ * 3. For example to take CLCD into resumed state use
++ echo -n 0 > /sys/devices/mb:c0/power/state
++ * 4. Similar things can be done for other devices. Few devices such as RTC,
++ * GPIO should not be takne into suspend state by this interface.
++ *
++ *
++ * 1.7 Enabling/Disabling Individual devices(Keypad, Touchpanel, MMC) as wakeup devices
++ *===================================================================================
++ * 1. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
++ * echo enabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
++ * 2. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
++ * echo disabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
++ * If a device's wakeup state is disabled, it cannot be used for waking the
++ * system from sleep.
++ * 3. Above steps are applicable for any device that can wakeup the system
++ *
++ *
++ * 1.8 To add a device that can be used to wakeup
++ *================================================
++ * 1. To make a platform device to be able to wakeup a system, change is
++ * required in board specific file like arch/arm/mach-nomadik/ndk15_devices.c
++ * 2. To make a amba device to be able to wakeup a system, change is required
++ * in platform specific file like arch/arm/mach-nomadik/stn8815_devices.c
++ *
++ *
++ *
++ */
++
++
+--- linux-2.6.20.orig/MAINTAINERS
++++ linux-2.6.20/MAINTAINERS
+@@ -1939,10 +1939,19 @@ M: ebiederm@xmission.com
+ W: http://www.xmission.com/~ebiederm/files/kexec/
+ L: linux-kernel@vger.kernel.org
+ L: fastboot@osdl.org
+ S: Maintained
+
++KGDB
++P: Tom Rini
++P: Amit S. Kale
++M: trini@kernel.crashing.org
++M: amitkale@linsyssoft.com
++W: http://sourceforge.net/projects/kgdb
++L: kgdb-bugreport@lists.sourceforge.net
++S: Maintained
++
+ KPROBES
+ P: Prasanna S Panchamukhi
+ M: prasanna@in.ibm.com
+ P: Ananth N Mavinakayanahalli
+ M: ananth@in.ibm.com
+--- linux-2.6.20.orig/Makefile
++++ linux-2.6.20/Makefile
+@@ -10,11 +10,11 @@ NAME = Homicidal Dwarf Hamster
+ # Comments in this file are targeted only to the developer, do not
+ # expect to learn how to build the kernel reading this file.
+
+ # Do not:
+ # o use make's built-in rules and variables
+-# (this increases performance and avoid hard-to-debug behavour);
++# (this increases performance and avoids hard-to-debug behaviour);
+ # o print "Entering directory ...";
+ MAKEFLAGS += -rR --no-print-directory
+
+ # We are using a recursive build, so we need to do a little thinking
+ # to get the ordering right.
+@@ -319,11 +319,11 @@ AFLAGS := -D__ASSEMBLY__
+ # Read KERNELRELEASE from include/config/kernel.release (if it exists)
+ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
+ KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+
+ export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
+-export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
++export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CFLAGS CROSS_COMPILE AS LD CC
+ export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
+ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
+
+ export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+ export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+@@ -495,11 +495,11 @@ CFLAGS += -fno-omit-frame-pointer $(cal
+ else
+ CFLAGS += -fomit-frame-pointer
+ endif
+
+ ifdef CONFIG_DEBUG_INFO
+-CFLAGS += -g
++CFLAGS += -gdwarf-2
+ endif
+
+ # Force gcc to behave correct even for buggy distributions
+ CFLAGS += $(call cc-option, -fno-stack-protector)
+
+@@ -528,11 +528,10 @@ export INSTALL_PATH ?= /boot
+ #
+ # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
+ # relocations required by build roots. This is not defined in the
+ # makefile but the argument can be passed to make if needed.
+ #
+-
+ MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
+ export MODLIB
+
+ #
+ # INSTALL_MOD_STRIP, if defined, will cause modules to be
+@@ -574,11 +573,11 @@ libs-y := $(libs-y1) $(libs-y2)
+
+ # Build vmlinux
+ # ---------------------------------------------------------------------------
+ # vmlinux is built from the objects selected by $(vmlinux-init) and
+ # $(vmlinux-main). Most are built-in.o files from top-level directories
+-# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
++# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
+ # Ordering when linking is important, and $(vmlinux-init) must be first.
+ #
+ # vmlinux
+ # ^
+ # |
+@@ -732,18 +731,20 @@ debug_kallsyms: .tmp_map$(last_kallsyms)
+
+ .tmp_map2: .tmp_map1
+
+ endif # ifdef CONFIG_KALLSYMS
+
++include $(srctree)/scripts/ksymhash/Makefile
+ # vmlinux image - including updated kernel symbols
+ vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
+ ifdef CONFIG_HEADERS_CHECK
+ $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
+ endif
+ $(call if_changed_rule,vmlinux__)
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
+ $(Q)rm -f .old_version
++ $(rule_ksymhash)
+
+ # The actual objects are generated when descending,
+ # make sure no implicit rule kicks in
+ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+
+@@ -1480,11 +1481,16 @@ endif
+ clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+
+ endif # skip-makefile
+
+ PHONY += FORCE
+-FORCE:
++include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk
++ mkdir -p include/linux/
++ awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h
++
++FORCE: include/linux/dwarf2-defs.h
++
+
+ # Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes.
+ Makefile: ;
+
+ # Declare the contents of the .PHONY variable as phony. We keep that
+--- linux-2.6.20.orig/arch/arm/Kconfig
++++ linux-2.6.20/arch/arm/Kconfig
+@@ -117,11 +117,11 @@ source "init/Kconfig"
+
+ menu "System Type"
+
+ choice
+ prompt "ARM system type"
+- default ARCH_VERSATILE
++ default ARCH_NOMADIK
+
+ config ARCH_AAEC2000
+ bool "Agilent AAEC-2000 based"
+ select ARM_AMBA
+ help
+@@ -201,10 +201,18 @@ config ARCH_NETX
+ bool "Hilscher NetX based"
+ select ARM_VIC
+ help
+ This enables support for systems based on the Hilscher NetX Soc
+
++config ARCH_NOMADIK
++ bool "Nomadik"
++ select ARM_AMBA
++ select ISA_DMA_API
++ select ICST525
++ help
++ Support for ARM's NOMADIK platform.
++
+ config ARCH_H720X
+ bool "Hynix HMS720x-based"
+ select ISA_DMA_API
+ help
+ This enables support for systems based on the Hynix HMS720x
+@@ -379,10 +387,11 @@ source "arch/arm/mach-realview/Kconfig"
+
+ source "arch/arm/mach-at91rm9200/Kconfig"
+
+ source "arch/arm/mach-netx/Kconfig"
+
++source "arch/arm/mach-nomadik/Kconfig"
+ # Definitions to make life easier
+ config ARCH_ACORN
+ bool
+
+ config PLAT_IOP
+@@ -738,11 +747,11 @@ config XIP_PHYS_ADDR
+ be linked for and stored to. This address is dependent on your
+ own flash usage.
+
+ endmenu
+
+-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
++if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_NOMADIK )
+
+ menu "CPU Frequency scaling"
+
+ source "drivers/cpufreq/Kconfig"
+
+@@ -774,10 +783,21 @@ config CPU_FREQ_IMX
+ help
+ This enables the CPUfreq driver for i.MX CPUs.
+
+ If in doubt, say N.
+
++config CPU_FREQ_NOMADIK
++ tristate "CPUfreq driver for ARM Nomadik CPUs"
++ depends on ARCH_NOMADIK && CPU_FREQ && NOMADIK_NDK15
++ default y
++ select NOMADIK_DMA
++ help
++ This enables the CPUfreq driver for ARM Nomadik CPUs.
++
++ For details, take a look at <file:Documentation/cpu-freq>.
++
++ If in doubt, say Y.
+ endmenu
+
+ endif
+
+ menu "Floating point emulation"
+@@ -908,10 +928,11 @@ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32
+ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+ || ARCH_IXP23XX
+ source "drivers/ide/Kconfig"
+ endif
+
++
+ source "drivers/scsi/Kconfig"
+
+ source "drivers/ata/Kconfig"
+
+ source "drivers/md/Kconfig"
+--- linux-2.6.20.orig/arch/arm/Makefile
++++ linux-2.6.20/arch/arm/Makefile
+@@ -18,11 +18,11 @@ GZFLAGS :=-9
+ # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+ CFLAGS +=$(call cc-option,-marm,)
+
+ # Do not use arch/arm/defconfig - it's always outdated.
+ # Select a platform tht is kept up-to-date
+-KBUILD_DEFCONFIG := versatile_defconfig
++KBUILD_DEFCONFIG := ndk15_defconfig
+
+ # defines filename extension depending memory manement type.
+ ifeq ($(CONFIG_MMU),)
+ MMUEXT := -nommu
+ endif
+@@ -87,10 +87,11 @@ CHECKFLAGS += -D__arm__
+
+ #Default value
+ head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
+ textofs-y := 0x00008000
+
++
+ machine-$(CONFIG_ARCH_RPC) := rpc
+ machine-$(CONFIG_ARCH_EBSA110) := ebsa110
+ machine-$(CONFIG_ARCH_CLPS7500) := clps7500
+ incdir-$(CONFIG_ARCH_CLPS7500) := cl7500
+ machine-$(CONFIG_FOOTBRIDGE) := footbridge
+@@ -104,10 +105,11 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
+ textofs-$(CONFIG_SA1111) := 0x00208000
+ endif
+ machine-$(CONFIG_ARCH_PXA) := pxa
+ machine-$(CONFIG_ARCH_L7200) := l7200
+ machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
++ machine-$(CONFIG_ARCH_NOMADIK) := nomadik
+ textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
+ machine-$(CONFIG_ARCH_CLPS711X) := clps711x
+ machine-$(CONFIG_ARCH_IOP32X) := iop32x
+ machine-$(CONFIG_ARCH_IOP33X) := iop33x
+ machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
+@@ -198,16 +200,25 @@ ifneq ($(KBUILD_SRC),)
+ else
+ $(Q)ln -fsn $(INCDIR) include/asm-arm/arch
+ endif
+ @touch $@
+
+-archprepare: maketools
++archprepare: maketools machprepare
+
+-PHONY += maketools FORCE
++PHONY += maketools machprepare machclean machmrproper FORCE
+ maketools: include/linux/version.h include/asm-arm/.arch FORCE
+ $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
+
++
++# Machine specific preparation if it exists
++MACHPREPARE_PATH = $(strip `grep "machprepare:" $(MACHINE)Makefile* | grep -o $(MACHINE)`)
++
++machprepare:
++ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
++ $(Q)set -e; for i in $(MACHPREPARE_PATH); do $(MAKE) -C $$i $@; done
++endif
++
+ # Convert bzImage to zImage
+ bzImage: zImage
+
+ zImage Image xipImage bootpImage uImage: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+@@ -216,12 +227,27 @@ zinstall install: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+
+ CLEAN_FILES += include/asm-arm/mach-types.h \
+ include/asm-arm/arch include/asm-arm/.arch
+
++# Machine specific mrproper operation if it exists
++MACHMRPROPER_PATH =`find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machmrproper: | sed 's/Makefile:machmrproper://g' | sed 's/Makefile://g'`
++
++machmrproper:
++ $(Q)set -e; for i in $(MACHMRPROPER_PATH); do $(MAKE) -C $$i $@; done
++
++# We use MRPROPER_FILES
++archmrproper: machmrproper
++
++# Machine specific clean operation
++MACHCLEAN_PATH = `find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machclean: | sed 's/Makefile:machclean://g' | sed 's/Makefile://g'`
++
++machclean:
++ $(Q)set -e; for i in $(MACHCLEAN_PATH); do $(MAKE) -C $$i $@; done
++
+ # We use MRPROPER_FILES and CLEAN_FILES now
+-archclean:
++archclean: machclean
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+ # My testing targets (bypasses dependencies)
+ bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
+ i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+--- linux-2.6.20.orig/arch/arm/common/rtctime.c
++++ linux-2.6.20/arch/arm/common/rtctime.c
+@@ -199,17 +199,17 @@ static int rtc_ioctl(struct inode *inode
+ ret = -EFAULT;
+ break;
+ }
+ alrm.enabled = 0;
+ alrm.pending = 0;
+- alrm.time.tm_mday = -1;
++/* alrm.time.tm_mday = -1;
+ alrm.time.tm_mon = -1;
+ alrm.time.tm_year = -1;
+ alrm.time.tm_wday = -1;
+ alrm.time.tm_yday = -1;
+ alrm.time.tm_isdst = -1;
+- ret = rtc_arm_set_alarm(ops, &alrm);
++*/ ret = rtc_arm_set_alarm(ops, &alrm);
+ break;
+
+ case RTC_RD_TIME:
+ ret = rtc_arm_read_time(ops, &tm);
+ if (ret)
+--- /dev/null
++++ linux-2.6.20/arch/arm/configs/ndk10_defconfig
+@@ -0,0 +1,1205 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.20
++# Thu Aug 16 17:17:58 2007
++#
++CONFIG_ARM=y
++# CONFIG_GENERIC_TIME is not set
++CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_IPC_NS is not set
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_UTS_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_SLAB=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_SLOB is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++
++#
+# Block layer
+#
+CONFIG_BLOCK=y
+# 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
+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
+# 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
+#
+# 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
+#
+# 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
+
+#
+# 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
+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
+
+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
+
+#
+# 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
+
+#
+#
+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
+# 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
+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
+# 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
+# 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
+
+# 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
+
+#
+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_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
+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
+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
+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_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
+#
+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
+
+#
+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
+# 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
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# 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
+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
+# 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
+# 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
+#
+# 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
+#
+# 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
+
+#
+# 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
+# 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
+
+#
+# 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
+# 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
+# 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
+#
+# 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
+#
+#
+# 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
+# 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
+#
+# 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
+#
+# 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
+# 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
+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
+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
+#
+# 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
+# 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_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
+#
+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
+# 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
+#
+# Profiling support
+#
-+CONFIG_PROFILING=y
-+CONFIG_OPROFILE=y
++# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+# 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
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
-diff -Nauprw linux-2.6.20/arch/arm/Kconfig ../new/linux-2.6.20/arch/arm/Kconfig
---- linux-2.6.20/arch/arm/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -119,7 +119,7 @@ menu "System Type"
-
- choice
- prompt "ARM system type"
-- default ARCH_VERSATILE
-+ default ARCH_NOMADIK
-
- config ARCH_AAEC2000
- bool "Agilent AAEC-2000 based"
-@@ -203,6 +203,14 @@ config ARCH_NETX
- help
- This enables support for systems based on the Hilscher NetX Soc
-
-+config ARCH_NOMADIK
-+ bool "Nomadik"
-+ select ARM_AMBA
-+ select ISA_DMA_API
-+ select ICST525
-+ help
-+ Support for ARM's NOMADIK platform.
-+
- config ARCH_H720X
- bool "Hynix HMS720x-based"
- select ISA_DMA_API
-@@ -381,6 +389,7 @@ source "arch/arm/mach-at91rm9200/Kconfig
-
- source "arch/arm/mach-netx/Kconfig"
-
-+source "arch/arm/mach-nomadik/Kconfig"
- # Definitions to make life easier
- config ARCH_ACORN
- bool
-@@ -740,7 +749,7 @@ config XIP_PHYS_ADDR
-
- endmenu
-
--if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
-+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_NOMADIK )
-
- menu "CPU Frequency scaling"
-
-@@ -776,6 +785,17 @@ config CPU_FREQ_IMX
-
- If in doubt, say N.
-
-+config CPU_FREQ_NOMADIK
-+ tristate "CPUfreq driver for ARM Nomadik CPUs"
-+ depends on ARCH_NOMADIK && CPU_FREQ && NOMADIK_NDK15
-+ default y
-+ select NOMADIK_DMA
-+ help
-+ This enables the CPUfreq driver for ARM Nomadik CPUs.
+--- /dev/null
++++ linux-2.6.20/arch/arm/configs/nhk15_defconfig
+@@ -0,0 +1,1458 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.20
++# Fri Aug 22 11:48:56 2008
++#
++CONFIG_ARM=y
++# CONFIG_GENERIC_TIME is not set
++CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
-+ For details, take a look at <file:Documentation/cpu-freq>.
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
+
-+ If in doubt, say Y.
- endmenu
-
- endif
-@@ -910,6 +930,7 @@ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32
- source "drivers/ide/Kconfig"
- endif
-
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_IPC_NS is not set
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_UTS_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_SLAB=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_SLOB is not set
+
- source "drivers/scsi/Kconfig"
-
- source "drivers/ata/Kconfig"
-diff -Nauprw linux-2.6.20/arch/arm/kernel/armksyms.c ../new/linux-2.6.20/arch/arm/kernel/armksyms.c
---- linux-2.6.20/arch/arm/kernel/armksyms.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/armksyms.c 2007-11-21 11:51:41.000000000 +0530
-@@ -31,6 +31,13 @@ extern void __lshrdi3(void);
- extern void __modsi3(void);
- extern void __muldi3(void);
- extern void __ucmpdi2(void);
-+#ifdef CONFIG_AEABI
-+extern void __aeabi_uldivmod(void);
-+#else
-+extern void __udivdi3(void);
-+#endif
-+extern void __umoddi3(void);
-+extern void __udivmoddi4(void);
- extern void __udivsi3(void);
- extern void __umodsi3(void);
- extern void __do_div64(void);
-@@ -139,6 +146,13 @@ EXPORT_SYMBOL(__modsi3);
- EXPORT_SYMBOL(__muldi3);
- EXPORT_SYMBOL(__ucmpdi2);
- EXPORT_SYMBOL(__udivsi3);
-+#ifdef CONFIG_AEABI
-+EXPORT_SYMBOL(__aeabi_uldivmod);
-+#else
-+EXPORT_SYMBOL(__udivdi3);
-+#endif
-+EXPORT_SYMBOL(__umoddi3);
-+EXPORT_SYMBOL(__udivmoddi4);
- EXPORT_SYMBOL(__umodsi3);
- EXPORT_SYMBOL(__do_div64);
-
-diff -Nauprw linux-2.6.20/arch/arm/kernel/dma.c ../new/linux-2.6.20/arch/arm/kernel/dma.c
---- linux-2.6.20/arch/arm/kernel/dma.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/dma.c 2007-11-21 11:51:41.000000000 +0530
-@@ -228,6 +228,7 @@ int dma_channel_active(dmach_t channel)
- {
- return dma_chan[channel].active;
- }
-+EXPORT_SYMBOL(dma_channel_active);
-
- void set_dma_page(dmach_t channel, char pagenr)
- {
-diff -Nauprw linux-2.6.20/arch/arm/kernel/entry-armv.S ../new/linux-2.6.20/arch/arm/kernel/entry-armv.S
---- linux-2.6.20/arch/arm/kernel/entry-armv.S 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/entry-armv.S 2007-11-21 11:51:41.000000000 +0530
-@@ -15,6 +15,7 @@
- * it to save wrong values... Be aware!
- */
-
-+#include <asm/kgdb.h>
- #include <asm/memory.h>
- #include <asm/glue.h>
- #include <asm/vfpmacros.h>
-@@ -239,6 +240,7 @@ svc_preempt:
- beq preempt_return @ go again
- b 1b
- #endif
-+ CFI_END_FRAME(__irq_svc)
-
- .align 5
- __und_svc:
-diff -Nauprw linux-2.6.20/arch/arm/kernel/irq.c ../new/linux-2.6.20/arch/arm/kernel/irq.c
---- linux-2.6.20/arch/arm/kernel/irq.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/irq.c 2007-11-21 11:51:41.000000000 +0530
-@@ -76,7 +76,19 @@ int show_interrupts(struct seq_file *p,
-
- seq_printf(p, "%3d: ", i);
- for_each_present_cpu(cpu)
-+#ifdef CONFIG_ARCH_NOMADIK
-+ /*
-+ * Outputs Priority Level for irq, if programmed
-+ * refer: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
-+ */
-+ if (action->flags & SA_IRQPRIORITY_MASK)
-+ seq_printf(p, "%10u:PL%02d", kstat_cpu(cpu).irqs[i],
-+ (int)(action->flags)>>4 & 0x0f);
-+ else
- seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
-+#else
-+ seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
-+#endif
- seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
- seq_printf(p, " %s", action->name);
- for (action = action->next; action; action = action->next)
-diff -Nauprw linux-2.6.20/arch/arm/kernel/kgdb.c ../new/linux-2.6.20/arch/arm/kernel/kgdb.c
---- linux-2.6.20/arch/arm/kernel/kgdb.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/kgdb.c 2008-10-20 13:37:44.000000000 +0530
-@@ -0,0 +1,208 @@
-+/*
-+ * arch/arm/kernel/kgdb.c
-+ *
-+ * ARM KGDB support
-+ *
-+ * Copyright (c) 2002-2004 MontaVista Software, Inc
-+ *
-+ * Authors: George Davis <davis_g@mvista.com>
-+ * Deepak Saxena <dsaxena@plexity.net>
-+ */
-+//#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/spinlock.h>
-+#include <linux/personality.h>
-+#include <linux/ptrace.h>
-+#include <linux/elf.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/kgdb.h>
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
+
-+#include <asm/atomic.h>
-+#include <asm/io.h>
-+#include <asm/pgtable.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unistd.h>
-+#include <asm/ptrace.h>
-+#include <asm/traps.h>
++#
++# Block layer
++#
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
+
-+/* Make a local copy of the registers passed into the handler (bletch) */
-+void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
-+{
-+ int regno;
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
+
-+ /* Initialize all to zero (??) */
-+ for (regno = 0; regno < GDB_MAX_REGS; regno++)
-+ gdb_regs[regno] = 0;
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++CONFIG_ARCH_NOMADIK=y
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_NOMADIK_NDK10_CUT_A1 is not set
++# CONFIG_NOMADIK_NDK10_CUT_B06 is not set
++# CONFIG_NOMADIK_NDK10_CUT_B0 is not set
++# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set
++# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set
++# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set
++# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set
++CONFIG_NOMADIK_NHK15=y
++CONFIG_NOMADIK_TARGET="NHK15"
++CONFIG_NOMADIK_SOC="stn8815"
++CONFIG_NOMADIK_PLATFORM="nhk15"
++CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=40 "
++CONFIG_NOMADIK_STN8815CAS22H11=y
+
-+ gdb_regs[_R0] = kernel_regs->ARM_r0;
-+ gdb_regs[_R1] = kernel_regs->ARM_r1;
-+ gdb_regs[_R2] = kernel_regs->ARM_r2;
-+ gdb_regs[_R3] = kernel_regs->ARM_r3;
-+ gdb_regs[_R4] = kernel_regs->ARM_r4;
-+ gdb_regs[_R5] = kernel_regs->ARM_r5;
-+ gdb_regs[_R6] = kernel_regs->ARM_r6;
-+ gdb_regs[_R7] = kernel_regs->ARM_r7;
-+ gdb_regs[_R8] = kernel_regs->ARM_r8;
-+ gdb_regs[_R9] = kernel_regs->ARM_r9;
-+ gdb_regs[_R10] = kernel_regs->ARM_r10;
-+ gdb_regs[_FP] = kernel_regs->ARM_fp;
-+ gdb_regs[_IP] = kernel_regs->ARM_ip;
-+ gdb_regs[_SP] = kernel_regs->ARM_sp;
-+ gdb_regs[_LR] = kernel_regs->ARM_lr;
-+ gdb_regs[_PC] = kernel_regs->ARM_pc;
-+ gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;
-+}
++#
++# Nomadik chip used STn8815
++#
++CONFIG_NOMADIK_GPIO=y
++CONFIG_NOMADIK_ENABLE_L2CACHE=y
++CONFIG_GPIO_PROC=y
++CONFIG_NOMADIK_DMA=y
++CONFIG_NOMADIK_SSP=y
++CONFIG_NOMADIK_MSP=y
++CONFIG_NOMADIK_MTU=m
++CONFIG_NOMADIK_MTU_SYSTEM_TICK=y
++CONFIG_NOMADIK_RTC=y
++CONFIG_NOMADIK_PM=y
++CONFIG_NOMADIK_SVA_INIT_MEM=y
++CONFIG_FORCE_MAX_ZONEORDER=13
++CONFIG_NOMADIK_SVA_MEM_SIZE=18
++CONFIG_NOMADIK_SVA_VPIP=y
++# CONFIG_NOMADIK_SAA_INIT_MEM is not set
++# CONFIG_FB_NOMADIK_VGA is not set
++# CONFIG_FB_NOMADIK_CRT is not set
++# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set
++# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set
++CONFIG_FB_NOMADIK_WVGA=y
++# CONFIG_FB_NOMADIK_PANEL_8BPP is not set
++# CONFIG_FB_NOMADIK_PANEL_16BPP is not set
++# CONFIG_FB_NOMADIK_PANEL_24BPP is not set
++CONFIG_FB_NOMADIK_PANEL_24BPP_PACKED=y
++CONFIG_FB_NOMADIK_ACCLN=y
++CONFIG_FB_NOMADIK_PANEL_BPP=24
++CONFIG_FB_NOMADIK_PANEL_NAME="WVGA"
++CONFIG_FB_NOMADIK_PANEL_XRES=800
++CONFIG_FB_NOMADIK_PANEL_YRES=480
++CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0xD6
++CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x27
++CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x22
++CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0xA
++CONFIG_FB_NOMADIK_PANEL_HSLEN=0x1
++CONFIG_FB_NOMADIK_PANEL_VSLEN=0x1
++CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x031f1822
+
-+/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
-+void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
-+{
-+ kernel_regs->ARM_r0 = gdb_regs[_R0];
-+ kernel_regs->ARM_r1 = gdb_regs[_R1];
-+ kernel_regs->ARM_r2 = gdb_regs[_R2];
-+ kernel_regs->ARM_r3 = gdb_regs[_R3];
-+ kernel_regs->ARM_r4 = gdb_regs[_R4];
-+ kernel_regs->ARM_r5 = gdb_regs[_R5];
-+ kernel_regs->ARM_r6 = gdb_regs[_R6];
-+ kernel_regs->ARM_r7 = gdb_regs[_R7];
-+ kernel_regs->ARM_r8 = gdb_regs[_R8];
-+ kernel_regs->ARM_r9 = gdb_regs[_R9];
-+ kernel_regs->ARM_r10 = gdb_regs[_R10];
-+ kernel_regs->ARM_fp = gdb_regs[_FP];
-+ kernel_regs->ARM_ip = gdb_regs[_IP];
-+ kernel_regs->ARM_sp = gdb_regs[_SP];
-+ kernel_regs->ARM_lr = gdb_regs[_LR];
-+ kernel_regs->ARM_pc = gdb_regs[_PC];
-+ kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1];
-+}
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++# CONFIG_CPU_ARM920T is not set
++CONFIG_L2CACHE_ENABLE=y
++CONFIG_CPU_ARM926T=y
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_ARM1022 is not set
++# CONFIG_CPU_ARM1026 is not set
++# CONFIG_CPU_V6 is not set
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
+
-+static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)
-+{
-+ return (struct pt_regs *)
-+ ((unsigned long)task->thread_info + THREAD_SIZE -
-+ 8 - sizeof(struct pt_regs));
-+}
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++CONFIG_ICST525=y
+
-+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
-+ struct task_struct *task)
-+{
-+ int regno;
-+ struct pt_regs *thread_regs;
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++CONFIG_ISA_DMA_API=y
+
-+ /* Just making sure... */
-+ if (task == NULL)
-+ return;
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
+
-+ /* Initialize to zero */
-+ for (regno = 0; regno < GDB_MAX_REGS; regno++)
-+ gdb_regs[regno] = 0;
++#
++# Kernel Features
++#
++CONFIG_PREEMPT=y
++CONFIG_NO_IDLE_HZ=y
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ALIGNMENT_TRAP=y
+
-+ /* Otherwise, we have only some registers from switch_to() */
-+ thread_regs = kgdb_get_user_regs(task);
-+ gdb_regs[_R0] = thread_regs->ARM_r0; /* Not really valid? */
-+ gdb_regs[_R1] = thread_regs->ARM_r1; /* " " */
-+ gdb_regs[_R2] = thread_regs->ARM_r2; /* " " */
-+ gdb_regs[_R3] = thread_regs->ARM_r3; /* " " */
-+ gdb_regs[_R4] = thread_regs->ARM_r4;
-+ gdb_regs[_R5] = thread_regs->ARM_r5;
-+ gdb_regs[_R6] = thread_regs->ARM_r6;
-+ gdb_regs[_R7] = thread_regs->ARM_r7;
-+ gdb_regs[_R8] = thread_regs->ARM_r8;
-+ gdb_regs[_R9] = thread_regs->ARM_r9;
-+ gdb_regs[_R10] = thread_regs->ARM_r10;
-+ gdb_regs[_FP] = thread_regs->ARM_fp;
-+ gdb_regs[_IP] = thread_regs->ARM_ip;
-+ gdb_regs[_SP] = thread_regs->ARM_sp;
-+ gdb_regs[_LR] = thread_regs->ARM_lr;
-+ gdb_regs[_PC] = thread_regs->ARM_pc;
-+ gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
-+}
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc mem=64M"
++# CONFIG_XIP_KERNEL is not set
+
-+static int compiled_break;
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++# CONFIG_CPU_FREQ_DEBUG is not set
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
++CONFIG_CPU_FREQ_NOMADIK=y
+
-+int kgdb_arch_handle_exception(int exception_vector, int signo,
-+ int err_code, char *remcom_in_buffer,
-+ char *remcom_out_buffer,
-+ struct pt_regs *linux_regs)
-+{
-+ long addr;
-+ char *ptr;
++#
++# Floating point emulation
++#
+
-+ switch (remcom_in_buffer[0]) {
-+ case 'c':
-+ kgdb_contthread = NULL;
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
+
-+ /*
-+ * Try to read optional parameter, pc unchanged if no parm.
-+ * If this was a compiled breakpoint, we need to move
-+ * to the next instruction or we will just breakpoint
-+ * over and over again.
-+ */
-+ ptr = &remcom_in_buffer[1];
-+ if (kgdb_hex2long(&ptr, &addr)) {
-+ linux_regs->ARM_pc = addr;
-+ } else if (compiled_break == 1) {
-+ linux_regs->ARM_pc += 4;
-+ }
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
+
-+ compiled_break = 0;
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_LEGACY is not set
++# CONFIG_PM_DEBUG is not set
++# CONFIG_PM_SYSFS_DEPRECATED is not set
++# CONFIG_APM is not set
+
-+ return 0;
-+ }
++#
++# Networking
++#
++CONFIG_NET=y
+
-+ return -1;
-+}
++#
++# Networking options
++#
++# CONFIG_NETDEBUG is not set
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++CONFIG_NET_KEY=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++CONFIG_NET_IPIP=y
++CONFIG_NET_IPGRE=y
++# CONFIG_NET_IPGRE_BROADCAST is not set
++CONFIG_IP_MROUTE=y
++# CONFIG_IP_PIMSM_V1 is not set
++# CONFIG_IP_PIMSM_V2 is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
+
-+static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
-+{
-+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
+
-+ return 0;
-+}
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
+
-+static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
-+{
-+ compiled_break = 1;
-+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
++#
++# TIPC Configuration (EXPERIMENTAL)
++#
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
+
-+ return 0;
-+}
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
+
-+static struct undef_hook kgdb_brkpt_hook = {
-+ .instr_mask = 0xffffffff,
-+ .instr_val = KGDB_BREAKINST,
-+ .fn = kgdb_brk_fn
-+};
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++CONFIG_BT_SCO=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HIDP=m
+
-+static struct undef_hook kgdb_compiled_brkpt_hook = {
-+ .instr_mask = 0xffffffff,
-+ .instr_val = KGDB_COMPILED_BREAK,
-+ .fn = kgdb_compiled_brk_fn
-+};
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIUSB is not set
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++CONFIG_BT_HCIVHCI=m
++# CONFIG_IEEE80211 is not set
++CONFIG_WIRELESS_EXT=y
+
-+/*
-+ * Register our undef instruction hooks with ARM undef core.
-+ * We regsiter a hook specifically looking for the KGB break inst
-+ * and we handle the normal undef case within the do_undefinstr
-+ * handler.
-+ */
-+int kgdb_arch_init(void)
-+{
-+ register_undef_hook(&kgdb_brkpt_hook);
-+ register_undef_hook(&kgdb_compiled_brkpt_hook);
++#
++# Device Drivers
++#
+
-+ return 0;
-+}
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_SYS_HYPERVISOR is not set
+
-+struct kgdb_arch arch_kgdb_ops = {
-+#ifndef __ARMEB__
-+ .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
-+#else
-+ .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
-+#endif
-+};
-diff -Nauprw linux-2.6.20/arch/arm/kernel/kgdb-jmp.S ../new/linux-2.6.20/arch/arm/kernel/kgdb-jmp.S
---- linux-2.6.20/arch/arm/kernel/kgdb-jmp.S 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/kgdb-jmp.S 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,30 @@
-+/*
-+ * arch/arm/kernel/kgdb-jmp.S
-+ *
-+ * Trivial setjmp and longjmp procedures to support bus error recovery
-+ * which may occur during kgdb memory read/write operations.
-+ *
-+ * Author: MontaVista Software, Inc. <source@mvista.com>
-+ * source@mvista.com
-+ *
-+ * 2002-2005 (c) MontaVista Software, Inc. This file is licensed under the
-+ * terms of the GNU General Public License version 2. This program as licensed
-+ * "as is" without any warranty of any kind, whether express or implied.
-+ */
-+#include <linux/linkage.h>
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
+
-+ENTRY (kgdb_fault_setjmp)
-+ /* Save registers */
-+ stmia r0, {r0-r14}
-+ str lr,[r0, #60]
-+ mrs r1,cpsr
-+ str r1,[r0,#64]
-+ ldr r1,[r0,#4]
-+ mov r0, #0
-+ mov pc,lr
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
+
-+ENTRY (kgdb_fault_longjmp)
-+ /* Restore registers */
-+ mov r1,#1
-+ str r1,[r0]
-+ ldmia r0,{r0-pc}^
-diff -Nauprw linux-2.6.20/arch/arm/kernel/Makefile ../new/linux-2.6.20/arch/arm/kernel/Makefile
---- linux-2.6.20/arch/arm/kernel/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -19,6 +19,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
- obj-$(CONFIG_ISA_DMA) += dma-isa.o
- obj-$(CONFIG_PCI) += bios32.o isa.o
- obj-$(CONFIG_SMP) += smp.o
-+obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o
- obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
-
- obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
-diff -Nauprw linux-2.6.20/arch/arm/kernel/setup.c ../new/linux-2.6.20/arch/arm/kernel/setup.c
---- linux-2.6.20/arch/arm/kernel/setup.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/setup.c 2007-11-21 11:51:41.000000000 +0530
-@@ -829,6 +829,11 @@ void __init setup_arch(char **cmdline_p)
- conswitchp = &dummy_con;
- #endif
- #endif
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
+
-+#if defined(CONFIG_KGDB)
-+ extern void __init early_trap_init(void);
-+ early_trap_init();
-+#endif
- }
-
-
-diff -Nauprw linux-2.6.20/arch/arm/kernel/traps.c ../new/linux-2.6.20/arch/arm/kernel/traps.c
---- linux-2.6.20/arch/arm/kernel/traps.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/traps.c 2007-11-21 11:51:41.000000000 +0530
-@@ -279,6 +279,7 @@ asmlinkage void do_undefinstr(struct pt_
- unsigned int instr;
- struct undef_hook *hook;
- siginfo_t info;
-+ mm_segment_t fs;
- void __user *pc;
-
- /*
-@@ -288,12 +289,15 @@ asmlinkage void do_undefinstr(struct pt_
- */
- regs->ARM_pc -= correction;
-
-+ fs = get_fs();
-+ set_fs(KERNEL_DS);
- pc = (void __user *)instruction_pointer(regs);
- if (thumb_mode(regs)) {
- get_user(instr, (u16 __user *)pc);
- } else {
- get_user(instr, (u32 __user *)pc);
- }
-+ set_fs(fs);
-
- spin_lock_irq(&undef_lock);
- list_for_each_entry(hook, &undef_hook, node) {
-@@ -682,6 +686,13 @@ EXPORT_SYMBOL(abort);
-
- void __init trap_init(void)
- {
-+#if defined(CONFIG_KGDB)
-+ return;
-+}
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_CFI_STAA=y
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
-+void __init early_trap_init(void)
-+{
-+#endif
- unsigned long vectors = CONFIG_VECTORS_BASE;
- extern char __stubs_start[], __stubs_end[];
- extern char __vectors_start[], __vectors_end[];
-diff -Nauprw linux-2.6.20/arch/arm/lib/gcclib.h ../new/linux-2.6.20/arch/arm/lib/gcclib.h
---- linux-2.6.20/arch/arm/lib/gcclib.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/gcclib.h 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,25 @@
-+/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
-+/* I Molton 29/07/01 */
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_NOMADIK=y
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_PLATRAM is not set
+
-+#define BITS_PER_UNIT 8
-+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
+
-+typedef unsigned int UQItype __attribute__ ((mode (QI)));
-+typedef int SItype __attribute__ ((mode (SI)));
-+typedef unsigned int USItype __attribute__ ((mode (SI)));
-+typedef int DItype __attribute__ ((mode (DI)));
-+typedef int word_type __attribute__ ((mode (__word__)));
-+typedef unsigned int UDItype __attribute__ ((mode (DI)));
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
+
-+#ifdef __ARMEB__
-+ struct DIstruct {SItype high, low;};
-+#else
-+ struct DIstruct {SItype low, high;};
-+#endif
++#
++# NAND Flash Device Drivers
++#
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_NOMADIK=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++CONFIG_MTD_ONENAND=y
++# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
++CONFIG_MTD_ONENAND_GENERIC=y
++# CONFIG_MTD_ONENAND_OTP is not set
++# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
++# CONFIG_MTD_ONENAND_SIM is not set
+
-+typedef union
-+{
-+ struct DIstruct s;
-+ DItype ll;
-+} DIunion;
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
+
-diff -Nauprw linux-2.6.20/arch/arm/lib/longlong.h ../new/linux-2.6.20/arch/arm/lib/longlong.h
---- linux-2.6.20/arch/arm/lib/longlong.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/longlong.h 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,184 @@
-+/* longlong.h -- based on code from gcc-2.95.3
++#
++# Plug and Play support
++#
+
-+ definitions for mixed size 32/64 bit arithmetic.
-+ Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=46080
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
+
-+ This definition file is free software; you can redistribute it
-+ and/or modify it under the terms of the GNU General Public
-+ License as published by the Free Software Foundation; either
-+ version 2, or (at your option) any later version.
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
+
-+ This definition file is distributed in the hope that it will be
-+ useful, but WITHOUT ANY WARRANTY; without even the implied
-+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+ See the GNU General Public License for more details.
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++CONFIG_SCSI_CONSTANTS=y
++CONFIG_SCSI_LOGGING=y
++CONFIG_SCSI_SCAN_ASYNC=y
+
-+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
+
-+#ifndef SI_TYPE_SIZE
-+#define SI_TYPE_SIZE 32
-+#endif
++#
++# SCSI low-level drivers
++#
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
+
-+#define __BITS4 (SI_TYPE_SIZE / 4)
-+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
-+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
-+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
-+
-+/* Define auxiliary asm macros.
-+
-+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
-+ multiplies two USItype integers MULTIPLER and MULTIPLICAND,
-+ and generates a two-part USItype product in HIGH_PROD and
-+ LOW_PROD.
-+
-+ 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
-+ and returns a UDItype product. This is just a variant of umul_ppmm.
-+
-+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
-+ denominator) divides a two-word unsigned integer, composed by the
-+ integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
-+ places the quotient in QUOTIENT and the remainder in REMAINDER.
-+ HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
-+ If, in addition, the most significant bit of DENOMINATOR must be 1,
-+ then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
-+
-+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
-+ denominator). Like udiv_qrnnd but the numbers are signed. The
-+ quotient is rounded towards 0.
-+
-+ 5) count_leading_zeros(count, x) counts the number of zero-bits from
-+ the msb to the first non-zero bit. This is the number of steps X
-+ needs to be shifted left to set the msb. Undefined for X == 0.
-+
-+ 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
-+ high_addend_2, low_addend_2) adds two two-word unsigned integers,
-+ composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
-+ LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
-+ LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
-+ lost.
++#
++# Serial ATA (prod) and Parallel ATA (experimental) drivers
++#
++# CONFIG_ATA is not set
+
-+ 7) sub_ddmmss(high_difference, low_difference, high_minuend,
-+ low_minuend, high_subtrahend, low_subtrahend) subtracts two
-+ two-word unsigned integers, composed by HIGH_MINUEND_1 and
-+ LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
-+ respectively. The result is placed in HIGH_DIFFERENCE and
-+ LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
-+ and is lost.
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
+
-+ If any of these macros are left undefined for a particular CPU,
-+ C macros are used. */
++#
++# Fusion MPT device support
++#
++# CONFIG_FUSION is not set
+
-+#if defined (__arm__)
-+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-+ __asm__ ("adds %1, %4, %5 \n\
-+ adc %0, %2, %3" \
-+ : "=r" ((USItype) (sh)), \
-+ "=&r" ((USItype) (sl)) \
-+ : "%r" ((USItype) (ah)), \
-+ "rI" ((USItype) (bh)), \
-+ "%r" ((USItype) (al)), \
-+ "rI" ((USItype) (bl)))
-+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-+ __asm__ ("subs %1, %4, %5 \n\
-+ sbc %0, %2, %3" \
-+ : "=r" ((USItype) (sh)), \
-+ "=&r" ((USItype) (sl)) \
-+ : "r" ((USItype) (ah)), \
-+ "rI" ((USItype) (bh)), \
-+ "r" ((USItype) (al)), \
-+ "rI" ((USItype) (bl)))
-+#define umul_ppmm(xh, xl, a, b) \
-+{register USItype __t0, __t1, __t2; \
-+ __asm__ ("%@ Inlined umul_ppmm \n\
-+ mov %2, %5, lsr #16 \n\
-+ mov %0, %6, lsr #16 \n\
-+ bic %3, %5, %2, lsl #16 \n\
-+ bic %4, %6, %0, lsl #16 \n\
-+ mul %1, %3, %4 \n\
-+ mul %4, %2, %4 \n\
-+ mul %3, %0, %3 \n\
-+ mul %0, %2, %0 \n\
-+ adds %3, %4, %3 \n\
-+ addcs %0, %0, #65536 \n\
-+ adds %1, %1, %3, lsl #16 \n\
-+ adc %0, %0, %3, lsr #16" \
-+ : "=&r" ((USItype) (xh)), \
-+ "=r" ((USItype) (xl)), \
-+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
-+ : "r" ((USItype) (a)), \
-+ "r" ((USItype) (b)));}
-+#define UMUL_TIME 20
-+#define UDIV_TIME 100
-+#endif /* __arm__ */
++#
++# IEEE 1394 (FireWire) support
++#
+
-+#define __umulsidi3(u, v) \
-+ ({DIunion __w; \
-+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
-+ __w.ll; })
++#
++# I2O device support
++#
+
-+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
-+ do { \
-+ USItype __d1, __d0, __q1, __q0; \
-+ USItype __r1, __r0, __m; \
-+ __d1 = __ll_highpart (d); \
-+ __d0 = __ll_lowpart (d); \
-+ \
-+ __r1 = (n1) % __d1; \
-+ __q1 = (n1) / __d1; \
-+ __m = (USItype) __q1 * __d0; \
-+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
-+ if (__r1 < __m) \
-+ { \
-+ __q1--, __r1 += (d); \
-+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
-+ if (__r1 < __m) \
-+ __q1--, __r1 += (d); \
-+ } \
-+ __r1 -= __m; \
-+ \
-+ __r0 = __r1 % __d1; \
-+ __q0 = __r1 / __d1; \
-+ __m = (USItype) __q0 * __d0; \
-+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
-+ if (__r0 < __m) \
-+ { \
-+ __q0--, __r0 += (d); \
-+ if (__r0 >= (d)) \
-+ if (__r0 < __m) \
-+ __q0--, __r0 += (d); \
-+ } \
-+ __r0 -= __m; \
-+ \
-+ (q) = (USItype) __q1 * __ll_B | __q0; \
-+ (r) = __r0; \
-+ } while (0)
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+
-+#define UDIV_NEEDS_NORMALIZATION 1
-+#define udiv_qrnnd __udiv_qrnnd_c
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
+
-+extern const UQItype __clz_tab[];
-+#define count_leading_zeros(count, x) \
-+ do { \
-+ USItype __xr = (x); \
-+ USItype __a; \
-+ \
-+ if (SI_TYPE_SIZE <= 32) \
-+ { \
-+ __a = __xr < ((USItype)1<<2*__BITS4) \
-+ ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
-+ : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
-+ } \
-+ else \
-+ { \
-+ for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
-+ if (((__xr >> __a) & 0xff) != 0) \
-+ break; \
-+ } \
-+ \
-+ (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
-+ } while (0)
-diff -Nauprw linux-2.6.20/arch/arm/lib/Makefile ../new/linux-2.6.20/arch/arm/lib/Makefile
---- linux-2.6.20/arch/arm/lib/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -13,7 +13,7 @@ lib-y := backtrace.o changebit.o csumip
- testchangebit.o testclearbit.o testsetbit.o \
- ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
- ucmpdi2.o lib1funcs.o div64.o sha1.o \
-- io-readsb.o io-writesb.o io-readsl.o io-writesl.o
-+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o udivdi3.o \
-
- mmu-y := clear_user.o copy_page.o getuser.o putuser.o
-
-diff -Nauprw linux-2.6.20/arch/arm/lib/udivdi3.c ../new/linux-2.6.20/arch/arm/lib/udivdi3.c
---- linux-2.6.20/arch/arm/lib/udivdi3.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/udivdi3.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,246 @@
-+/* More subroutines needed by GCC output code on some machines. */
-+/* Compile this one with gcc. */
-+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
+
-+This file is part of GNU CC.
++#
++# Ethernet (1000 Mbit)
++#
+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
++#
++# Ethernet (10000 Mbit)
++#
+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
++#
++# Token Ring devices
++#
+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
-+/* As a special exception, if you link this library with other files,
-+ some of which are compiled with GCC, to produce an executable,
-+ this library does not by itself cause the resulting executable
-+ to be covered by the GNU General Public License.
-+ This exception does not however invalidate any other reasons why
-+ the executable file might be covered by the GNU General Public License.
-+ */
-+/* support functions required by the kernel. based on code from gcc-2.95.3 */
-+/* I Molton 29/07/01 */
++#
++# Obsolete Wireless cards support (pre-802.11)
++#
++# CONFIG_STRIP is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_HOSTAP is not set
+
-+#include "gcclib.h"
-+#include "longlong.h"
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+
-+const UQItype __clz_tab[] =
-+{
-+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+};
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
+
-+UDItype
-+__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
-+{
-+ DIunion ww;
-+ DIunion nn, dd;
-+ DIunion rr;
-+ USItype d0, d1, n0, n1, n2;
-+ USItype q0, q1;
-+ USItype b, bm;
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
+
-+ nn.ll = n;
-+ dd.ll = d;
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
+
-+ d0 = dd.s.low;
-+ d1 = dd.s.high;
-+ n0 = nn.s.low;
-+ n1 = nn.s.high;
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_KEYPAD_NOMADIK=y
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_UCB1400 is not set
++# CONFIG_TOUCHSCREEN_NOMADIK is not set
++CONFIG_TOUCHSCREEN_NOMADIK_TS2003=y
++# CONFIG_INPUT_MISC is not set
+
-+ if (d1 == 0)
-+ {
-+ if (d0 > n1)
-+ {
-+ /* 0q = nn / 0D */
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
+
-+ count_leading_zeros (bm, d0);
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
+
-+ if (bm != 0)
-+ {
-+ /* Normalize, i.e. make the most significant bit of the
-+ denominator set. */
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
+
-+ d0 = d0 << bm;
-+ n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
-+ n0 = n0 << bm;
-+ }
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++CONFIG_SERIAL_AMBA_PL011=y
++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
+
-+ udiv_qrnnd (q0, n0, n1, n0, d0);
-+ q1 = 0;
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
+
-+ /* Remainder in n0 >> bm. */
-+ }
-+ else
-+ {
-+ /* qq = NN / 0d */
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
+
-+ if (d0 == 0)
-+ d0 = 1 / d0; /* Divide intentionally by zero. */
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
+
-+ count_leading_zeros (bm, d0);
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_CHARDEV=y
+
-+ if (bm == 0)
-+ {
-+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
-+ conclude (the most significant bit of n1 is set) /\ (the
-+ leading quotient digit q1 = 1).
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
+
-+ This special case is necessary, not an optimization.
-+ (Shifts counts of SI_TYPE_SIZE are undefined.) */
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_NOMADIK=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_PCA_ISA is not set
+
-+ n1 -= d0;
-+ q1 = 1;
-+ }
-+ else
-+ {
-+ /* Normalize. */
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
+
-+ b = SI_TYPE_SIZE - bm;
++#
++# SPI support
++#
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
+
-+ d0 = d0 << bm;
-+ n2 = n1 >> b;
-+ n1 = (n1 << bm) | (n0 >> b);
-+ n0 = n0 << bm;
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_BITBANG is not set
++CONFIG_NOMADIK_SPI=y
+
-+ udiv_qrnnd (q1, n1, n2, n1, d0);
-+ }
++#
++# SPI Protocol Masters
++#
+
-+ /* n1 != d0... */
++#
++# Dallas's 1-wire bus
++#
++# CONFIG_W1 is not set
+
-+ udiv_qrnnd (q0, n0, n1, n0, d0);
++#
++# Hardware Monitoring support
++#
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_ABITUGURU is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ASB100 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_FSCHER is not set
++# CONFIG_SENSORS_FSCPOS is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++CONFIG_SENSORS_LIS3LV02DL=m
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
+
-+ /* Remainder in n0 >> bm. */
-+ }
++#
++# Misc devices
++#
++CONFIG_STMPE_NOMADIK=y
++CONFIG_SIF_NOMADIK=y
++CONFIG_ETM_NOMADIK=m
++# CONFIG_TIFM_CORE is not set
++CONFIG_BATT_NOMADIK=y
++#
++# LED devices
++#
++# CONFIG_NEW_LEDS is not set
+
-+ if (rp != 0)
-+ {
-+ rr.s.low = n0 >> bm;
-+ rr.s.high = 0;
-+ *rp = rr.ll;
-+ }
-+ }
-+ else
-+ {
-+ if (d1 > n1)
-+ {
-+ /* 00 = nn / DD */
++#
++# LED drivers
++#
+
-+ q0 = 0;
-+ q1 = 0;
++#
++# LED Triggers
++#
+
-+ /* Remainder in n1n0. */
-+ if (rp != 0)
-+ {
-+ rr.s.low = n0;
-+ rr.s.high = n1;
-+ *rp = rr.ll;
-+ }
-+ }
-+ else
-+ {
-+ /* 0q = NN / dd */
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++# CONFIG_VIDEO_V4L1 is not set
++CONFIG_VIDEO_V4L1_COMPAT=y
++CONFIG_VIDEO_V4L2=y
+
-+ count_leading_zeros (bm, d1);
-+ if (bm == 0)
-+ {
-+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
-+ conclude (the most significant bit of n1 is set) /\ (the
-+ quotient digit q0 = 0 or 1).
++#
++# Video Capture Adapters
++#
+
-+ This special case is necessary, not an optimization. */
++#
++# Video Capture Adapters
++#
++# CONFIG_VIDEO_ADV_DEBUG is not set
++CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
++# CONFIG_VIDEO_VIVI is not set
++# CONFIG_VIDEO_SAA5246A is not set
++# CONFIG_VIDEO_SAA5249 is not set
+
-+ /* The condition on the next line takes advantage of that
-+ n1 >= d1 (true due to program flow). */
-+ if (n1 > d1 || n0 >= d0)
-+ {
-+ q0 = 1;
-+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
-+ }
-+ else
-+ q0 = 0;
++#
++# V4L USB devices
++#
++# CONFIG_VIDEO_PVRUSB2 is not set
++# CONFIG_VIDEO_USBVISION is not set
++CONFIG_VIDEO_NOMADIK=y
+
-+ q1 = 0;
++#
++# Radio Adapters
++#
++# CONFIG_USB_DSBR is not set
+
-+ if (rp != 0)
-+ {
-+ rr.s.low = n0;
-+ rr.s.high = n1;
-+ *rp = rr.ll;
-+ }
-+ }
-+ else
-+ {
-+ USItype m1, m0;
-+ /* Normalize. */
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
+
-+ b = SI_TYPE_SIZE - bm;
++#
++# NOMADIK Audio Video Drivers(SAA and SVA)
++#
++CONFIG_NOMADIK_SAA=m
++CONFIG_NOMADIK_SVA=m
++CONFIG_NOMADIK_OGL=m
++# CONFIG_USB_DABUSB is not set
+
-+ d1 = (d1 << bm) | (d0 >> b);
-+ d0 = d0 << bm;
-+ n2 = n1 >> b;
-+ n1 = (n1 << bm) | (n0 >> b);
-+ n0 = n0 << bm;
++#
++# Graphics support
++#
++CONFIG_FIRMWARE_EDID=y
++CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++# CONFIG_FB_TILEBLITTING is not set
++CONFIG_FB_ARMCLCD=y
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
+
-+ udiv_qrnnd (q0, n1, n2, n1, d1);
-+ umul_ppmm (m1, m0, q0, d0);
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
+
-+ if (m1 > n1 || (m1 == n1 && m0 > n0))
-+ {
-+ q0--;
-+ sub_ddmmss (m1, m0, m1, m0, d1, d0);
-+ }
++#
++# Logo configuration
++#
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
-+ q1 = 0;
++#
++# Sound
++#
++CONFIG_NOMADIK_ACODEC=y
++# CONFIG_NOMADIK_STW5094 is not set
++CONFIG_NOMADIK_STW5095=y
++CONFIG_SOUND=y
+
-+ /* Remainder in (n1n0 - m1m0) >> bm. */
-+ if (rp != 0)
-+ {
-+ sub_ddmmss (n1, n0, n1, n0, m1, m0);
-+ rr.s.low = (n1 << b) | (n0 >> bm);
-+ rr.s.high = n1 >> bm;
-+ *rp = rr.ll;
-+ }
-+ }
-+ }
-+ }
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
+
-+ ww.s.low = q0;
-+ ww.s.high = q1;
-+ return ww.ll;
-+}
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
+
-+UDItype
-+#ifdef CONFIG_AEABI
-+__aeabi_uldivmod (UDItype n, UDItype d)
-+#else
-+__udivdi3 (UDItype n, UDItype d)
-+#endif
-+{
-+ return __udivmoddi4 (n, d, (UDItype *) 0);
-+}
++#
++# ALSA ARM devices
++#
++CONFIG_SND_NOMADIK_ALSA=m
++CONFIG_SND_ARMAACI=y
+
-+UDItype
-+__umoddi3 (UDItype u, UDItype v)
-+{
-+ UDItype w;
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
+
-+ (void) __udivmoddi4 (u ,v, &w);
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
+
-+ return w;
-+}
++#
++# HID Devices
++#
++CONFIG_HID=y
+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/clock.c ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.c
---- linux-2.6.20/arch/arm/mach-nomadik/clock.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,127 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/clock.c
-+ *
-+ * Copyright (C) 2004 ARM Limited.
-+ * Written by Deep Blue Solutions Limited.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/errno.h>
-+#include <linux/err.h>
-+#include <linux/string.h>
-+#include <linux/clk.h>
-+#include <linux/mutex.h>
++#
++# USB support
++#
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++#CONFIG_USB_DEBUG is not set
+
-+#include <asm/semaphore.h>
-+#include <asm/hardware/icst525.h>
-+#include "clock.h"
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_BANDWIDTH=y
++CONFIG_USB_DYNAMIC_MINORS=y
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
+
-+static LIST_HEAD(clocks);
-+static DEFINE_MUTEX(clocks_mutex);
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
+
-+struct clk *clk_get(struct device *dev, const char *id)
-+{
-+ struct clk *p, *clk = ERR_PTR(-ENOENT);
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
+
-+ mutex_lock(&clocks_mutex);
-+ list_for_each_entry(p, &clocks, node) {
-+ if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-+ clk = p;
-+ break;
-+ }
-+ }
-+ mutex_unlock(&clocks_mutex);
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
+
-+ return clk;
-+}
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++#CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
+
-+EXPORT_SYMBOL(clk_get);
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++# CONFIG_USB_AIPTEK is not set
++# CONFIG_USB_WACOM is not set
++# CONFIG_USB_ACECAD is not set
++# CONFIG_USB_KBTAB is not set
++# CONFIG_USB_POWERMATE is not set
++# CONFIG_USB_TOUCHSCREEN is not set
++# CONFIG_USB_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE is not set
++# CONFIG_USB_ATI_REMOTE2 is not set
++# CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
+
-+void clk_put(struct clk *clk)
-+{
-+ module_put(clk->owner);
-+}
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
+
-+EXPORT_SYMBOL(clk_put);
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET_MII is not set
++# CONFIG_USB_USBNET is not set
++CONFIG_USB_MON=y
+
-+int clk_enable(struct clk *clk)
-+{
-+ return 0;
-+}
++#
++# USB port drivers
++#
+
-+EXPORT_SYMBOL(clk_enable);
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
+
-+void clk_disable(struct clk *clk)
-+{
-+}
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++CONFIG_USB_TEST=y
+
-+EXPORT_SYMBOL(clk_disable);
++#
++# USB DSL modem support
++#
+
-+unsigned long clk_get_rate(struct clk *clk)
-+{
-+ return clk->rate;
-+}
++#
++# USB Gadget Support
++#
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_AT91 is not set
++CONFIG_USB_GADGET_DUMMY_HCD=y
++CONFIG_USB_DUMMY_HCD=m
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++# CONFIG_USB_ETH is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_MIDI_GADGET is not set
++CONFIG_USB_INVENTRA_HCD=m
++CONFIG_USB_INVENTRA_HCD_HOST=y
++# CONFIG_USB_INVENTRA_HCD_GADGET_API is not set
++# CONFIG_USB_INVENTRA_HCD_OTG is not set
++# CONFIG_USB_INVENTRA_HCD_OTG_GSTORAGE is not set
++# CONFIG_USB_INVENTRA_STATIC_CONFIG is not set
++# CONFIG_USB_INVENTRA_DMA is not set
++# CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID is not set
++CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE=""
++CONFIG_USB_INVENTRA_MUSB_BOARD_FILE=""
++CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS=""
++# CONFIG_USB_INVENTRA_HCD_POLLING is not set
++CONFIG_USB_INVENTRA_HCD_LOGGING=0
+
-+EXPORT_SYMBOL(clk_get_rate);
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
+
-+long clk_round_rate(struct clk *clk, unsigned long rate)
-+{
-+ return 0;
-+}
++#
++# Real Time Clock
++#
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
+
-+EXPORT_SYMBOL(clk_round_rate);
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
+
-+int clk_set_rate(struct clk *clk, unsigned long rate)
-+{
-+ clk->rate = rate;
-+ return 0;
-+}
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
+
-+EXPORT_SYMBOL(clk_set_rate);
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="cp437"
++# CONFIG_NTFS_FS is not set
+
-+/*
-+ * These are fixed clocks.
-+ */
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_CONFIGFS_FS is not set
+
-+static struct clk uart_clk = {
-+ .name = "UARTCLK",
-+ .rate = 48000000,
-+};
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
+
-+static struct clk clcd_clk = {
-+ .name = "CLCDCLK",
-+ .rate = 48000000,
-+};
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++CONFIG_NFS_V4=y
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
+
-+int clk_register(struct clk *clk)
-+{
-+ mutex_lock(&clocks_mutex);
-+ list_add(&clk->node, &clocks);
-+ mutex_unlock(&clocks_mutex);
-+ return 0;
-+}
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
+
-+EXPORT_SYMBOL(clk_register);
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="cp437"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
+
-+void clk_unregister(struct clk *clk)
-+{
-+ mutex_lock(&clocks_mutex);
-+ list_del(&clk->node);
-+ mutex_unlock(&clocks_mutex);
-+}
++#
++# Distributed Lock Manager
++#
++# CONFIG_DLM is not set
+
-+EXPORT_SYMBOL(clk_unregister);
++#
++# Profiling support
++#
++CONFIG_PROFILING=y
++CONFIG_OPROFILE=y
+
-+static int __init clk_init(void)
-+{
-+ clk_register(&uart_clk);
-+ clk_register(&clcd_clk);
-+ return 0;
-+}
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
++# CONFIG_DEBUG_USER is not set
+
-+arch_initcall(clk_init);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/clock.h ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.h
---- linux-2.6.20/arch/arm/mach-nomadik/clock.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.h 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,25 @@
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_LRW is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Hardware crypto devices
++#
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_IOMAP_COPY=y
+--- linux-2.6.20.orig/arch/arm/kernel/Makefile
++++ linux-2.6.20/arch/arm/kernel/Makefile
+@@ -17,10 +17,11 @@ obj-$(CONFIG_FIQ) += fiq.o
+ obj-$(CONFIG_MODULES) += armksyms.o module.o
+ obj-$(CONFIG_ARTHUR) += arthur.o
+ obj-$(CONFIG_ISA_DMA) += dma-isa.o
+ obj-$(CONFIG_PCI) += bios32.o isa.o
+ obj-$(CONFIG_SMP) += smp.o
++obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o
+ obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
+
+ obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
+ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
+
+--- linux-2.6.20.orig/arch/arm/kernel/armksyms.c
++++ linux-2.6.20/arch/arm/kernel/armksyms.c
+@@ -29,10 +29,17 @@ extern void __ashrdi3(void);
+ extern void __divsi3(void);
+ extern void __lshrdi3(void);
+ extern void __modsi3(void);
+ extern void __muldi3(void);
+ extern void __ucmpdi2(void);
++#ifdef CONFIG_AEABI
++extern void __aeabi_uldivmod(void);
++#else
++extern void __udivdi3(void);
++#endif
++extern void __umoddi3(void);
++extern void __udivmoddi4(void);
+ extern void __udivsi3(void);
+ extern void __umodsi3(void);
+ extern void __do_div64(void);
+
+ extern void __aeabi_idiv(void);
+@@ -137,10 +144,17 @@ EXPORT_SYMBOL(__divsi3);
+ EXPORT_SYMBOL(__lshrdi3);
+ EXPORT_SYMBOL(__modsi3);
+ EXPORT_SYMBOL(__muldi3);
+ EXPORT_SYMBOL(__ucmpdi2);
+ EXPORT_SYMBOL(__udivsi3);
++#ifdef CONFIG_AEABI
++EXPORT_SYMBOL(__aeabi_uldivmod);
++#else
++EXPORT_SYMBOL(__udivdi3);
++#endif
++EXPORT_SYMBOL(__umoddi3);
++EXPORT_SYMBOL(__udivmoddi4);
+ EXPORT_SYMBOL(__umodsi3);
+ EXPORT_SYMBOL(__do_div64);
+
+ #ifdef CONFIG_AEABI
+ EXPORT_SYMBOL(__aeabi_idiv);
+--- linux-2.6.20.orig/arch/arm/kernel/dma.c
++++ linux-2.6.20/arch/arm/kernel/dma.c
+@@ -226,10 +226,11 @@ EXPORT_SYMBOL(disable_dma);
+ */
+ int dma_channel_active(dmach_t channel)
+ {
+ return dma_chan[channel].active;
+ }
++EXPORT_SYMBOL(dma_channel_active);
+
+ void set_dma_page(dmach_t channel, char pagenr)
+ {
+ printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
+ }
+--- linux-2.6.20.orig/arch/arm/kernel/entry-armv.S
++++ linux-2.6.20/arch/arm/kernel/entry-armv.S
+@@ -13,10 +13,11 @@
+ *
+ * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
+ * it to save wrong values... Be aware!
+ */
+
++#include <asm/kgdb.h>
+ #include <asm/memory.h>
+ #include <asm/glue.h>
+ #include <asm/vfpmacros.h>
+ #include <asm/arch/entry-macro.S>
+ #include <asm/thread_notify.h>
+@@ -237,10 +238,11 @@ svc_preempt:
+ ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS
+ tst r0, #_TIF_NEED_RESCHED
+ beq preempt_return @ go again
+ b 1b
+ #endif
++ CFI_END_FRAME(__irq_svc)
+
+ .align 5
+ __und_svc:
+ svc_entry
+
+--- linux-2.6.20.orig/arch/arm/kernel/irq.c
++++ linux-2.6.20/arch/arm/kernel/irq.c
+@@ -74,11 +74,23 @@ int show_interrupts(struct seq_file *p,
+ if (!action)
+ goto unlock;
+
+ seq_printf(p, "%3d: ", i);
+ for_each_present_cpu(cpu)
++#ifdef CONFIG_ARCH_NOMADIK
++ /*
++ * Outputs Priority Level for irq, if programmed
++ * refer: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
++ */
++ if (action->flags & SA_IRQPRIORITY_MASK)
++ seq_printf(p, "%10u:PL%02d", kstat_cpu(cpu).irqs[i],
++ (int)(action->flags)>>4 & 0x0f);
++ else
+ seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
++#else
++ seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
++#endif
+ seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
+ seq_printf(p, " %s", action->name);
+ for (action = action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+
+--- /dev/null
++++ linux-2.6.20/arch/arm/kernel/kgdb-jmp.S
+@@ -0,0 +1,30 @@
+/*
-+ * linux/arch/arm/mach-nomadik/clock.h
++ * arch/arm/kernel/kgdb-jmp.S
+ *
-+ * Copyright (C) 2004 ARM Limited.
-+ * Written by Deep Blue Solutions Limited.
++ * Trivial setjmp and longjmp procedures to support bus error recovery
++ * which may occur during kgdb memory read/write operations.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * Author: MontaVista Software, Inc. <source@mvista.com>
++ * source@mvista.com
++ *
++ * 2002-2005 (c) MontaVista Software, Inc. This file is licensed under the
++ * terms of the GNU General Public License version 2. This program as licensed
++ * "as is" without any warranty of any kind, whether express or implied.
+ */
-+struct module;
-+struct icst525_params;
++#include <linux/linkage.h>
+
-+struct clk {
-+ struct list_head node;
-+ unsigned long rate;
-+ struct module *owner;
-+ const char *name;
-+ const struct icst525_params *params;
-+ void *data;
-+ void (*setvco)(struct clk *, struct icst525_vco vco);
-+};
++ENTRY (kgdb_fault_setjmp)
++ /* Save registers */
++ stmia r0, {r0-r14}
++ str lr,[r0, #60]
++ mrs r1,cpsr
++ str r1,[r0,#64]
++ ldr r1,[r0,#4]
++ mov r0, #0
++ mov pc,lr
+
-+int clk_register(struct clk *clk);
-+void clk_unregister(struct clk *clk);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/cpu.c ../new/linux-2.6.20/arch/arm/mach-nomadik/cpu.c
---- linux-2.6.20/arch/arm/mach-nomadik/cpu.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/cpu.c 2008-07-04 23:45:03.000000000 +0530
-@@ -0,0 +1,293 @@
++ENTRY (kgdb_fault_longjmp)
++ /* Restore registers */
++ mov r1,#1
++ str r1,[r0]
++ ldmia r0,{r0-pc}^
+--- /dev/null
++++ linux-2.6.20/arch/arm/kernel/kgdb.c
+@@ -0,0 +1,208 @@
+/*
-+ * linux/arch/arm/mach-nomadik/cpu.c
-+ *
-+ * Copyright (C) STMicroelectronics
++ * arch/arm/kernel/kgdb.c
+ *
++ * ARM KGDB support
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * Copyright (c) 2002-2004 MontaVista Software, Inc
+ *
-+ * CPU freq driver
++ * Authors: George Davis <davis_g@mvista.com>
++ * Deepak Saxena <dsaxena@plexity.net>
+ */
-+#include <linux/module.h>
++//#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
-+#include <linux/cpufreq.h>
-+#include <linux/slab.h>
++#include <linux/signal.h>
+#include <linux/sched.h>
-+#include <linux/smp.h>
++#include <linux/mm.h>
++#include <linux/spinlock.h>
++#include <linux/personality.h>
++#include <linux/ptrace.h>
++#include <linux/elf.h>
++#include <linux/interrupt.h>
+#include <linux/init.h>
++#include <linux/kgdb.h>
+
-+#include <asm/hardware.h>
++#include <asm/atomic.h>
+#include <asm/io.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/i2c.h>
-+#include <asm/arch/power.h>
-+
-+#include <asm/arch/debug.h>
-+
-+#define CPUFREQ_NAME "CPUFREQ"
-+
-+#ifndef CPUFREQ_DEBUG
-+#define CPUFREQ_DEBUG 0
-+#endif
-+
-+#define NMDK_DEBUG CPUFREQ_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX CPUFREQ_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
-+
-+
-+#define PLL1_CRYSTAL_FREQ_KHZ (192 * 100)
-+#define CALC_FREQ(pll1_nmul, pll1_pdiv) (PLL1_CRYSTAL_FREQ_KHZ * (pll1_nmul + 2)) / (1 << pll1_pdiv);
-+
-+static struct cpufreq_driver nomadik_driver;
-+static unsigned int nomadik_get(unsigned int cpu);
-+
-+extern unsigned int nomadik_freq_to_idx(unsigned int freq);
-+extern unsigned int nomadik_idx_to_freq(unsigned int idx);
-+extern u32 nomadik_setsys_freq(u32 freq_idx);
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/unistd.h>
++#include <asm/ptrace.h>
++#include <asm/traps.h>
+
-+/*
-+ * Validate the speed policy.
-+ */
-+static int nomadik_verify_policy(struct cpufreq_policy *policy)
++/* Make a local copy of the registers passed into the handler (bletch) */
++void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
+{
++ int regno;
+
-+ nmdk_dbg_ftrace();
-+ cpufreq_verify_within_limits(policy,
-+ policy->cpuinfo.min_freq,
-+ policy->cpuinfo.max_freq);
-+
-+ policy->min = NOMADIK_CPUFREQ_MIN;
-+ policy->max = NOMADIK_CPUFREQ_MAX;
-+
-+ cpufreq_verify_within_limits(policy,
-+ policy->cpuinfo.min_freq,
-+ policy->cpuinfo.max_freq);
++ /* Initialize all to zero (??) */
++ for (regno = 0; regno < GDB_MAX_REGS; regno++)
++ gdb_regs[regno] = 0;
+
-+ return 0;
++ gdb_regs[_R0] = kernel_regs->ARM_r0;
++ gdb_regs[_R1] = kernel_regs->ARM_r1;
++ gdb_regs[_R2] = kernel_regs->ARM_r2;
++ gdb_regs[_R3] = kernel_regs->ARM_r3;
++ gdb_regs[_R4] = kernel_regs->ARM_r4;
++ gdb_regs[_R5] = kernel_regs->ARM_r5;
++ gdb_regs[_R6] = kernel_regs->ARM_r6;
++ gdb_regs[_R7] = kernel_regs->ARM_r7;
++ gdb_regs[_R8] = kernel_regs->ARM_r8;
++ gdb_regs[_R9] = kernel_regs->ARM_r9;
++ gdb_regs[_R10] = kernel_regs->ARM_r10;
++ gdb_regs[_FP] = kernel_regs->ARM_fp;
++ gdb_regs[_IP] = kernel_regs->ARM_ip;
++ gdb_regs[_SP] = kernel_regs->ARM_sp;
++ gdb_regs[_LR] = kernel_regs->ARM_lr;
++ gdb_regs[_PC] = kernel_regs->ARM_pc;
++ gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;
+}
+
-+static int nomadik_set_target(struct cpufreq_policy *policy,
-+ unsigned int target_freq, unsigned int relation)
++/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
++void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
+{
-+ cpumask_t cpus_allowed;
-+ int cpu = policy->cpu;
-+ struct cpufreq_freqs freqs;
-+ unsigned int freq_idx;
-+ unsigned int new_voltage, cur_voltage;
-+ unsigned char vcore_data;
-+ int result;
-+
-+ nmdk_dbg2("%s called with target_freq = %d relation = %d\n",
-+ (__FUNCTION__), target_freq, relation);
-+ /*
-+ * Save this threads cpus_allowed mask.
-+ */
-+ cpus_allowed = current->cpus_allowed;
-+
-+ /*
-+ * Bind to the specified CPU. When this call returns,
-+ * we should be running on the right CPU.
-+ */
-+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
-+ BUG_ON(cpu != smp_processor_id());
-+
-+ freqs.old = nomadik_get(policy->cpu);
-+
-+ freq_idx = nomadik_freq_to_idx(target_freq);
-+
-+ switch (relation) {
-+ case CPUFREQ_RELATION_L:
-+ if (nomadik_idx_to_freq(freq_idx) > policy->max)
-+ freq_idx--;
-+ break;
-+ case CPUFREQ_RELATION_H:
-+ if ((nomadik_idx_to_freq(freq_idx) > target_freq) &&
-+ (nomadik_idx_to_freq(freq_idx - 1) >= policy->min))
-+ freq_idx--;
-+ break;
-+ }
-+
-+ freqs.new = nomadik_idx_to_freq(freq_idx);
-+ freqs.cpu = policy->cpu;
-+
-+ nmdk_dbg2(" freqs.new = %d\n", freqs.new);
-+ if (freqs.old == freqs.new) {
-+ set_cpus_allowed(current, cpus_allowed);
-+ return 0;
-+ }
-+
-+#if 0
-+ if ( freq_idx == 0)
-+ {
-+ nomadik_normal_to_slow = 1;
-+ nomadik_slow_to_normal = 0;
-+ }
-+ if (freqs.old == 19200 )
-+ {
-+ nomadik_slow_to_normal = 1;
-+ nomadik_normal_to_slow = 0;
-+
-+ }
-+#endif
-+
-+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++ kernel_regs->ARM_r0 = gdb_regs[_R0];
++ kernel_regs->ARM_r1 = gdb_regs[_R1];
++ kernel_regs->ARM_r2 = gdb_regs[_R2];
++ kernel_regs->ARM_r3 = gdb_regs[_R3];
++ kernel_regs->ARM_r4 = gdb_regs[_R4];
++ kernel_regs->ARM_r5 = gdb_regs[_R5];
++ kernel_regs->ARM_r6 = gdb_regs[_R6];
++ kernel_regs->ARM_r7 = gdb_regs[_R7];
++ kernel_regs->ARM_r8 = gdb_regs[_R8];
++ kernel_regs->ARM_r9 = gdb_regs[_R9];
++ kernel_regs->ARM_r10 = gdb_regs[_R10];
++ kernel_regs->ARM_fp = gdb_regs[_FP];
++ kernel_regs->ARM_ip = gdb_regs[_IP];
++ kernel_regs->ARM_sp = gdb_regs[_SP];
++ kernel_regs->ARM_lr = gdb_regs[_LR];
++ kernel_regs->ARM_pc = gdb_regs[_PC];
++ kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1];
++}
+
-+ new_voltage = nomadik_freq_to_voltage(freqs.new);
-+ cur_voltage = g_nomadik_voltage;
-+ nmdk_dbg2(" new voltage = %d\n", new_voltage);
-+ nmdk_dbg2(" old voltage = %d\n", cur_voltage);
++static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)
++{
++ return (struct pt_regs *)
++ ((unsigned long)task->thread_info + THREAD_SIZE -
++ 8 - sizeof(struct pt_regs));
++}
+
-+ if (new_voltage > cur_voltage) {
++void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
++ struct task_struct *task)
++{
++ int regno;
++ struct pt_regs *thread_regs;
+
-+ vcore_data = new_voltage;
++ /* Just making sure... */
++ if (task == NULL)
++ return;
+
-+ result =
-+ nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
-+ 0x1E, 1);
-+ if (unlikely(result)) {
-+ nmdk_error("i2c write error with ret = %d\n", result);
-+ goto err1;
++ /* Initialize to zero */
++ for (regno = 0; regno < GDB_MAX_REGS; regno++)
++ gdb_regs[regno] = 0;
+
-+ } else
-+ nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
++ /* Otherwise, we have only some registers from switch_to() */
++ thread_regs = kgdb_get_user_regs(task);
++ gdb_regs[_R0] = thread_regs->ARM_r0; /* Not really valid? */
++ gdb_regs[_R1] = thread_regs->ARM_r1; /* " " */
++ gdb_regs[_R2] = thread_regs->ARM_r2; /* " " */
++ gdb_regs[_R3] = thread_regs->ARM_r3; /* " " */
++ gdb_regs[_R4] = thread_regs->ARM_r4;
++ gdb_regs[_R5] = thread_regs->ARM_r5;
++ gdb_regs[_R6] = thread_regs->ARM_r6;
++ gdb_regs[_R7] = thread_regs->ARM_r7;
++ gdb_regs[_R8] = thread_regs->ARM_r8;
++ gdb_regs[_R9] = thread_regs->ARM_r9;
++ gdb_regs[_R10] = thread_regs->ARM_r10;
++ gdb_regs[_FP] = thread_regs->ARM_fp;
++ gdb_regs[_IP] = thread_regs->ARM_ip;
++ gdb_regs[_SP] = thread_regs->ARM_sp;
++ gdb_regs[_LR] = thread_regs->ARM_lr;
++ gdb_regs[_PC] = thread_regs->ARM_pc;
++ gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
++}
+
-+#ifdef CPUFREQ_DEBUG
-+ vcore_data = 0;
++static int compiled_break;
+
-+ result =
-+ nomadik_i2c_read_register(I2C_TOUAREG_CLIENT, &vcore_data,
-+ 0x1E, 1);
-+ if (unlikely(result)) {
-+ nmdk_error("i2c read error with ret = %d\n", result);
-+ goto err1;
++int kgdb_arch_handle_exception(int exception_vector, int signo,
++ int err_code, char *remcom_in_buffer,
++ char *remcom_out_buffer,
++ struct pt_regs *linux_regs)
++{
++ long addr;
++ char *ptr;
+
-+ } else
-+ nmdk_dbg2("i2c read vcore_data = 0x%x\n", vcore_data);
++ switch (remcom_in_buffer[0]) {
++ case 'c':
++ kgdb_contthread = NULL;
+
-+ if ( vcore_data != new_voltage )
-+ {
-+ printk("i2c had not written correctly\n");
-+ goto err1;
++ /*
++ * Try to read optional parameter, pc unchanged if no parm.
++ * If this was a compiled breakpoint, we need to move
++ * to the next instruction or we will just breakpoint
++ * over and over again.
++ */
++ ptr = &remcom_in_buffer[1];
++ if (kgdb_hex2long(&ptr, &addr)) {
++ linux_regs->ARM_pc = addr;
++ } else if (compiled_break == 1) {
++ linux_regs->ARM_pc += 4;
+ }
-+#endif
-+ g_nomadik_voltage = new_voltage;
-+ }
-+
-+ nomadik_setsys_freq(freq_idx);
-+
-+ if (new_voltage < cur_voltage) {
-+
-+ vcore_data = new_voltage;
-+ result =
-+ nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
-+ 0x1E, 1);
-+ /**
-+ * Here even if we are not able to set lower voltage. Still system can
-+ * work with previous voltage
-+ */
-+
-+ if (unlikely(result)) {
-+ nmdk_error("i2c write error with ret = %d\n", result);
-+ goto err1;
-+
-+ } else
-+ nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
-+ g_nomadik_voltage = new_voltage;
-+
-+ }
-+
-+ err1:
+
-+ /*
-+ * Restore the CPUs allowed mask.
-+ */
-+ set_cpus_allowed(current, cpus_allowed);
++ compiled_break = 0;
+
-+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-+#if CPUFREQ_DEBUG
-+ {
-+ int j;
-+ for(j=0; j <= 0x124; j+=4)
-+ printk("sdmc[%x] = %x\n", j, readl(0xf0110000 + j ));
++ return 0;
+ }
-+#endif
+
-+ return 0;
++ return -1;
+}
+
-+#define SRC_PLL_FREQ_OFFSET 0x14
-+static unsigned int nomadik_get(unsigned int cpu)
++static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
+{
-+ cpumask_t cpus_allowed;
-+ unsigned int current_freq;
-+ unsigned char __iomem *src_base;
-+ unsigned long pll_reg;
-+ unsigned int pll1_nmul, pll1_pdiv;
-+
-+ nmdk_dbg_ftrace();
-+ cpus_allowed = current->cpus_allowed;
-+
-+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
-+ BUG_ON(cpu != smp_processor_id());
-+ src_base = (unsigned char *)IO_ADDRESS(NOMADIK_SRC_BASE);
-+ if ( ( readl(src_base) & 0x78 ) == 0x20 )
-+ {
-+ pll_reg = readl(src_base + SRC_PLL_FREQ_OFFSET);
-+ pll1_pdiv = pll_reg & 0x7;
-+ pll1_nmul = (pll_reg >> 8) & 0x3f;
-+ current_freq = CALC_FREQ(pll1_nmul, pll1_pdiv);
-+ }
-+ else
-+ current_freq = NOMADIK_CPUFREQ_MIN;
-+
-+ set_cpus_allowed(current, cpus_allowed);
-+ nmdk_dbg2("Current_freq = %d\n", current_freq);
-+ nmdk_dbg2("pll1_nmul = 0x%x pll1_pdiv = 0x%x\n", pll1_nmul, pll1_pdiv);
++ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
-+ g_nomadik_voltage = nomadik_freq_to_voltage(current_freq);
-+ nmdk_dbg2("g_nomadik_voltage = %x\n", g_nomadik_voltage);
-+ return current_freq;
++ return 0;
+}
+
-+static int nomadik_cpufreq_init(struct cpufreq_policy *policy)
++static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
+{
-+
-+ /* set default policy and cpuinfo */
-+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-+ policy->cpuinfo.max_freq = NOMADIK_CPUFREQ_MAX;
-+ policy->cpuinfo.min_freq = NOMADIK_CPUFREQ_MIN;
-+ policy->cpuinfo.transition_latency = NOMADIK_CPUFREQ_TRANS_LATENCY;
-+ policy->cur = policy->min = policy->max = nomadik_get(policy->cpu);
-+ nmdk_dbg2("max cpu freq = %d min cpu freq = %d\n", NOMADIK_CPUFREQ_MAX,
-+ NOMADIK_CPUFREQ_MIN);
++ compiled_break = 1;
++ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+ return 0;
+}
+
-+static struct cpufreq_driver nomadik_driver = {
-+ .verify = nomadik_verify_policy,
-+ .target = nomadik_set_target,
-+ .get = nomadik_get,
-+ .init = nomadik_cpufreq_init,
-+ .name = "nomadik-cpufreq",
++static struct undef_hook kgdb_brkpt_hook = {
++ .instr_mask = 0xffffffff,
++ .instr_val = KGDB_BREAKINST,
++ .fn = kgdb_brk_fn
+};
+
-+static int __init nomadik_cpu_init(void)
-+{
-+ return cpufreq_register_driver(&nomadik_driver);
-+}
++static struct undef_hook kgdb_compiled_brkpt_hook = {
++ .instr_mask = 0xffffffff,
++ .instr_val = KGDB_COMPILED_BREAK,
++ .fn = kgdb_compiled_brk_fn
++};
+
-+static void __exit nomadik_cpu_exit(void)
++/*
++ * Register our undef instruction hooks with ARM undef core.
++ * We regsiter a hook specifically looking for the KGB break inst
++ * and we handle the normal undef case within the do_undefinstr
++ * handler.
++ */
++int kgdb_arch_init(void)
+{
-+ cpufreq_unregister_driver(&nomadik_driver);
-+}
-+
-+MODULE_AUTHOR("Manish Rathi");
-+MODULE_DESCRIPTION("cpufreq driver for ARM Nomadik CPUs");
-+MODULE_LICENSE("GPL");
-+
-+module_init(nomadik_cpu_init);
-+module_exit(nomadik_cpu_exit);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl ../new/linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl
---- linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,55 @@
-+#! /usr/bin/perl
-+#
-+# gen_nomadik_kconfig.pl: Generates Kconfig in arch/arm/mach-nomadik/ considering all board specific Kconfig files.
++ register_undef_hook(&kgdb_brkpt_hook);
++ register_undef_hook(&kgdb_compiled_brkpt_hook);
+
-+$VAR=@ARGV;
-+if (@ARGV != 1)
-+{
-+ print "Usage: ./create_kconfig.pl <filepath>\n";
-+ print "example: ./create_kconfig.pl arch/arm/mach-nomadik\n";
-+ exit(1);
++ return 0;
+}
+
-+$KPATH=@ARGV[0];
-+
-+@temp=split(/mach-/, $KPATH);
-+@temp1=split(/\//, @temp[1]);
-+$mach=@temp1[0];
-+$machuc=uc($mach);
++struct kgdb_arch arch_kgdb_ops = {
++#ifndef __ARMEB__
++ .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
++#else
++ .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
++#endif
++};
+--- linux-2.6.20.orig/arch/arm/kernel/setup.c
++++ linux-2.6.20/arch/arm/kernel/setup.c
+@@ -827,10 +827,15 @@ void __init setup_arch(char **cmdline_p)
+ conswitchp = &vga_con;
+ #elif defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+ #endif
+ #endif
+
-+if ( -e "$KPATH/Kconfig" ) {
-+ exit(0);
++#if defined(CONFIG_KGDB)
++ extern void __init early_trap_init(void);
++ early_trap_init();
++#endif
+ }
+
+
+ static int __init topology_init(void)
+ {
+--- linux-2.6.20.orig/arch/arm/kernel/traps.c
++++ linux-2.6.20/arch/arm/kernel/traps.c
+@@ -277,25 +277,29 @@ asmlinkage void do_undefinstr(struct pt_
+ {
+ unsigned int correction = thumb_mode(regs) ? 2 : 4;
+ unsigned int instr;
+ struct undef_hook *hook;
+ siginfo_t info;
++ mm_segment_t fs;
+ void __user *pc;
+
+ /*
+ * According to the ARM ARM, PC is 2 or 4 bytes ahead,
+ * depending whether we're in Thumb mode or not.
+ * Correct this offset.
+ */
+ regs->ARM_pc -= correction;
+
++ fs = get_fs();
++ set_fs(KERNEL_DS);
+ pc = (void __user *)instruction_pointer(regs);
+ if (thumb_mode(regs)) {
+ get_user(instr, (u16 __user *)pc);
+ } else {
+ get_user(instr, (u32 __user *)pc);
+ }
++ set_fs(fs);
+
+ spin_lock_irq(&undef_lock);
+ list_for_each_entry(hook, &undef_hook, node) {
+ if ((instr & hook->instr_mask) == hook->instr_val &&
+ (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
+@@ -680,10 +684,17 @@ void abort(void)
+ }
+ EXPORT_SYMBOL(abort);
+
+ void __init trap_init(void)
+ {
++#if defined(CONFIG_KGDB)
++ return;
+}
+
-+open (KCONFIG, "> $KPATH/Kconfig") || die "Can't open file: $!";
-+$Kconfig_data="# Automatically generated Kconfig: don't edit\n# To add new board support create $KPATH/<board>_Kconfig file\n\nif ARCH_$machuc\n\nchoice\n\nprompt \"$mach target board\"\n\n";
-+print KCONFIG $Kconfig_data;
-+
-+@filenames =qx(ls $KPATH/*_Kconfig);
-+foreach $filename(@filenames)
-+ {
-+ @temp=split(/mach-$mach\//, $filename);
-+ @temp1=split(/_Kconfig/, @temp[1]);
-+ $filename=@temp1[0];
-+ chomp($filename);
-+ $filenameuc=uc($filename);
-+ $usc="_";
-+ print KCONFIG "config $machuc$usc$filenameuc\n\tbool \"$filename\"\n\thelp\n\t\tSupprots $filename target board for $mach platform\n\n";
-+ };
-+
-+print KCONFIG "endchoice\n\n";
-+
-+@filenames =qx(ls $KPATH/*_Kconfig);
-+foreach $filename(@filenames)
-+ {
-+ chomp($filename);
-+ print KCONFIG "source \"$filename\"\n\n";
-+ };
++void __init early_trap_init(void)
++{
++#endif
+ unsigned long vectors = CONFIG_VECTORS_BASE;
+ extern char __stubs_start[], __stubs_end[];
+ extern char __vectors_start[], __vectors_end[];
+ extern char __kuser_helper_start[], __kuser_helper_end[];
+ int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+--- linux-2.6.20.orig/arch/arm/lib/Makefile
++++ linux-2.6.20/arch/arm/lib/Makefile
+@@ -11,11 +11,11 @@ lib-y := backtrace.o changebit.o csumip
+ strncpy_from_user.o strnlen_user.o \
+ strchr.o strrchr.o \
+ testchangebit.o testclearbit.o testsetbit.o \
+ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+ ucmpdi2.o lib1funcs.o div64.o sha1.o \
+- io-readsb.o io-writesb.o io-readsl.o io-writesl.o
++ io-readsb.o io-writesb.o io-readsl.o io-writesl.o udivdi3.o \
+
+ mmu-y := clear_user.o copy_page.o getuser.o putuser.o
+
+ # the code in uaccess.S is not preemption safe and
+ # probably faster on ARMv3 only
+--- /dev/null
++++ linux-2.6.20/arch/arm/lib/gcclib.h
+@@ -0,0 +1,25 @@
++/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
++/* I Molton 29/07/01 */
+
-+if ( -e "$KPATH/Kconfig-$mach" ) {
-+ print KCONFIG "source \"$KPATH/Kconfig-$mach\"\n";
-+}
++#define BITS_PER_UNIT 8
++#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
-+print KCONFIG "endif\n\n";
-+close KCONFIG;
++typedef unsigned int UQItype __attribute__ ((mode (QI)));
++typedef int SItype __attribute__ ((mode (SI)));
++typedef unsigned int USItype __attribute__ ((mode (SI)));
++typedef int DItype __attribute__ ((mode (DI)));
++typedef int word_type __attribute__ ((mode (__word__)));
++typedef unsigned int UDItype __attribute__ ((mode (DI)));
+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S ../new/linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S
---- linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S 2008-10-20 13:37:44.000000000 +0530
-@@ -0,0 +1,655 @@
-+/*
-+ * arch/arm/mach-nomadik/deep_sleep.S
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
++#ifdef __ARMEB__
++ struct DIstruct {SItype high, low;};
++#else
++ struct DIstruct {SItype low, high;};
++#endif
+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/entry-macro.S>
++typedef union
++{
++ struct DIstruct s;
++ DItype ll;
++} DIunion;
+
-+.global nomadik_deep_sleep
-+.extern L2dummyPointer
-+
-+nomadik_deep_sleep:
-+ /*Store all the general purpose registers along with the link register*/
-+ stmfd sp!,{r0-r12,lr}
+--- /dev/null
++++ linux-2.6.20/arch/arm/lib/longlong.h
+@@ -0,0 +1,184 @@
++/* longlong.h -- based on code from gcc-2.95.3
+
-+ /* save the first parameter passed to function nomadik_deep_sleep to r12*/
-+ mov r12,r0
-+
-+ /* save the second parameter passed to function nomadik_deep_sleep to the variable addr - mpmc_base*/
-+ ldr r11, =mpmc_base
-+ str r1,[r11]
-+
-+ /* save the third parameter passed to function nomadik_deep_sleep to the variable addr - backup_ram_base */
-+ ldr r11, =backup_ram_base
-+ str r2,[r11]
++ definitions for mixed size 32/64 bit arithmetic.
++ Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
++ This definition file is free software; you can redistribute it
++ and/or modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation; either
++ version 2, or (at your option) any later version.
+
-+
-+ ldr r11, =backup_ram_store
-+ mov r10,#0x250
-+ add r10, r2, r10
-+ str r10, [r11, #0x0]
++ This definition file is distributed in the hope that it will be
++ useful, but WITHOUT ANY WARRANTY; without even the implied
++ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++ See the GNU General Public License for more details.
+
-+#ifdef DEEP_SLEEP_DEBUG
-+ /*Clean entire DCache using test and clean*/
-+clean_dcache_start:
-+ mrc p15,0,r15,c7,c14,3
-+ bne clean_dcache_start
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
+
-+ /* Invalidate I cache and Dcache */
-+ mov r0,#0
-+ mcr p15,0,r0,c7,c7,0
++/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
-+ /*Drain Write Buffers*/
-+ mov r0,#0
-+ mcr p15,0,r0,c7,c10,4
++#ifndef SI_TYPE_SIZE
++#define SI_TYPE_SIZE 32
+#endif
-+
-+ /* Storing the enabled values of VIC */
-+ ldr r0, =vic_base
-+ ldr r0, [r0,#0x0]
-+
-+ ldr r1, [r0,#0xC] /* Interrupt sslection register */
-+ ldr r2, [r0, #0x2C]
-+ ldr r3, [r0, #0x10] /* Interrupt Enable register */
-+ ldr r4, [r0, #0x30]
-+ ldr r5, [r0, #0x54] /* Default VAR */
-+ stmfd sp!, {r1-r5}
+
++#define __BITS4 (SI_TYPE_SIZE / 4)
++#define __ll_B (1L << (SI_TYPE_SIZE / 2))
++#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
++#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
++/* Define auxiliary asm macros.
+
-+ ldr r1,[r0,#0x100]
-+ ldr r2,[r0,#0x104]
-+ ldr r3,[r0,#0x108]
-+ ldr r4,[r0,#0x10C]
-+ ldr r5,[r0,#0x110]
-+ ldr r6,[r0,#0x114]
-+ ldr r7,[r0,#0x118]
-+ ldr r8,[r0,#0x11C]
-+ ldr r9,[r0,#0x120]
-+ ldr r10,[r0,#0x124]
-+ ldr r11,[r0,#0x128]
-+ stmfd sp!,{r1-r11}
++ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
++ multiplies two USItype integers MULTIPLER and MULTIPLICAND,
++ and generates a two-part USItype product in HIGH_PROD and
++ LOW_PROD.
+
-+ ldr r1,[r0,#0x12C]
-+ ldr r2,[r0,#0x130]
-+ ldr r3,[r0,#0x134]
-+ ldr r4,[r0,#0x138]
-+ ldr r5,[r0,#0x13C]
-+ ldr r6,[r0,#0x200]
-+ ldr r7,[r0,#0x204]
-+ ldr r8,[r0,#0x208]
-+ ldr r9,[r0,#0x20C]
-+ ldr r10,[r0,#0x210]
-+ ldr r11,[r0,#0x214]
-+ stmfd sp!,{r1-r11}
++ 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
++ and returns a UDItype product. This is just a variant of umul_ppmm.
+
++ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
++ denominator) divides a two-word unsigned integer, composed by the
++ integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
++ places the quotient in QUOTIENT and the remainder in REMAINDER.
++ HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
++ If, in addition, the most significant bit of DENOMINATOR must be 1,
++ then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
-+ ldr r1,[r0,#0x218]
-+ ldr r2,[r0,#0x21C]
-+ ldr r3,[r0,#0x220]
-+ ldr r4,[r0,#0x224]
-+ ldr r5,[r0,#0x228]
-+ ldr r6,[r0,#0x22C]
-+ ldr r7,[r0,#0x230]
-+ ldr r8,[r0,#0x234]
-+ ldr r9,[r0,#0x238]
-+ ldr r10,[r0,#0x23C]
-+ stmfd sp!,{r1-r10}
++ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
++ denominator). Like udiv_qrnnd but the numbers are signed. The
++ quotient is rounded towards 0.
+
++ 5) count_leading_zeros(count, x) counts the number of zero-bits from
++ the msb to the first non-zero bit. This is the number of steps X
++ needs to be shifted left to set the msb. Undefined for X == 0.
+
++ 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
++ high_addend_2, low_addend_2) adds two two-word unsigned integers,
++ composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
++ LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
++ LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
++ lost.
+
++ 7) sub_ddmmss(high_difference, low_difference, high_minuend,
++ low_minuend, high_subtrahend, low_subtrahend) subtracts two
++ two-word unsigned integers, composed by HIGH_MINUEND_1 and
++ LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
++ respectively. The result is placed in HIGH_DIFFERENCE and
++ LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
++ and is lost.
+
++ If any of these macros are left undefined for a particular CPU,
++ C macros are used. */
+
-+ mrc p15,0, r0,c5,c0,0 /* FSR--Domain Fault */
-+ mrc p15,0, r1,c5,c0,1 /* FSR--Instruction Fault */
-+
-+ mrc p15,0, r2,c6,c0,0 /* FAR */
-+
-+ mrc p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
-+ mrc p15,0, r4,c9,c0,1 /* Read ICache Lockdown */
-+
-+ mrc p15,0, r5,c9,c1,0 /* Read Data TLB */
-+ mrc p15,0, r6,c9,c1,1 /* Read Instruction TCM region register */
-+
-+ mrc p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
-+
-+ mrc p15,0, r8,c13,c0,0 /* FCSE--PID */
-+ mrc p15,0, r9,c13,c0,1 /* Context-ID */
-+
-+ /* Save all these registers onto the stack */
-+ stmfd sp!, {r0-r9}
-+
-+ /*Move sp to non banked register. sp is not shared in banked modes.*/
-+ mov r6, sp
-+
-+ /* Store the two user mode registers*/
-+ sub r6,r6,#0x8
-+ stmia r6, {sp, lr}^
-+ mov r0,r0
++#if defined (__arm__)
++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
++ __asm__ ("adds %1, %4, %5 \n\
++ adc %0, %2, %3" \
++ : "=r" ((USItype) (sh)), \
++ "=&r" ((USItype) (sl)) \
++ : "%r" ((USItype) (ah)), \
++ "rI" ((USItype) (bh)), \
++ "%r" ((USItype) (al)), \
++ "rI" ((USItype) (bl)))
++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
++ __asm__ ("subs %1, %4, %5 \n\
++ sbc %0, %2, %3" \
++ : "=r" ((USItype) (sh)), \
++ "=&r" ((USItype) (sl)) \
++ : "r" ((USItype) (ah)), \
++ "rI" ((USItype) (bh)), \
++ "r" ((USItype) (al)), \
++ "rI" ((USItype) (bl)))
++#define umul_ppmm(xh, xl, a, b) \
++{register USItype __t0, __t1, __t2; \
++ __asm__ ("%@ Inlined umul_ppmm \n\
++ mov %2, %5, lsr #16 \n\
++ mov %0, %6, lsr #16 \n\
++ bic %3, %5, %2, lsl #16 \n\
++ bic %4, %6, %0, lsl #16 \n\
++ mul %1, %3, %4 \n\
++ mul %4, %2, %4 \n\
++ mul %3, %0, %3 \n\
++ mul %0, %2, %0 \n\
++ adds %3, %4, %3 \n\
++ addcs %0, %0, #65536 \n\
++ adds %1, %1, %3, lsl #16 \n\
++ adc %0, %0, %3, lsr #16" \
++ : "=&r" ((USItype) (xh)), \
++ "=r" ((USItype) (xl)), \
++ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
++ : "r" ((USItype) (a)), \
++ "r" ((USItype) (b)));}
++#define UMUL_TIME 20
++#define UDIV_TIME 100
++#endif /* __arm__ */
+
-+ /* Save current mode with interrupts disabled*/
-+ mrs r7, cpsr
-+ stmfd r6!, {r7}
-+ bic r7,r7,#0xf
++#define __umulsidi3(u, v) \
++ ({DIunion __w; \
++ umul_ppmm (__w.s.high, __w.s.low, u, v); \
++ __w.ll; })
+
-+ /* move the first par from r12 to r3 */
-+ mov r3,r12
-+
-+ /** Following are the registers that are used
-+ R6:- Stack Pointer
-+ R7:- CPSR Value [IRQ Disabled , FIQ Disabled, Mode bit Cleared]
-+ R8:- Virtual Address of Backup SRAM (0xA0010250)
-+ R9:- UART1 Base Register [Debug Device Base Register]
-+ R10:- MPMC Base Register
-+ R11:- SRC Base Register
-+ R12:- PMU Base Register
-+ */
-+
-+ ldr r8,=backup_ram_store
-+ ldr r8, [r8,#0]
++#define __udiv_qrnnd_c(q, r, n1, n0, d) \
++ do { \
++ USItype __d1, __d0, __q1, __q0; \
++ USItype __r1, __r0, __m; \
++ __d1 = __ll_highpart (d); \
++ __d0 = __ll_lowpart (d); \
++ \
++ __r1 = (n1) % __d1; \
++ __q1 = (n1) / __d1; \
++ __m = (USItype) __q1 * __d0; \
++ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
++ if (__r1 < __m) \
++ { \
++ __q1--, __r1 += (d); \
++ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
++ if (__r1 < __m) \
++ __q1--, __r1 += (d); \
++ } \
++ __r1 -= __m; \
++ \
++ __r0 = __r1 % __d1; \
++ __q0 = __r1 / __d1; \
++ __m = (USItype) __q0 * __d0; \
++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
++ if (__r0 < __m) \
++ { \
++ __q0--, __r0 += (d); \
++ if (__r0 >= (d)) \
++ if (__r0 < __m) \
++ __q0--, __r0 += (d); \
++ } \
++ __r0 -= __m; \
++ \
++ (q) = (USItype) __q1 * __ll_B | __q0; \
++ (r) = __r0; \
++ } while (0)
+
-+ ldr r9,=uart1_base
-+ ldr r9, [r9,#0]
-+
-+ ldr r10,=mpmc_base
-+ ldr r10, [r10,#0]
++#define UDIV_NEEDS_NORMALIZATION 1
++#define udiv_qrnnd __udiv_qrnnd_c
+
-+ ldr r11,=src_base
-+ ldr r11, [r11,#0]
++extern const UQItype __clz_tab[];
++#define count_leading_zeros(count, x) \
++ do { \
++ USItype __xr = (x); \
++ USItype __a; \
++ \
++ if (SI_TYPE_SIZE <= 32) \
++ { \
++ __a = __xr < ((USItype)1<<2*__BITS4) \
++ ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
++ : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
++ } \
++ else \
++ { \
++ for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
++ if (((__xr >> __a) & 0xff) != 0) \
++ break; \
++ } \
++ \
++ (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
++ } while (0)
+--- /dev/null
++++ linux-2.6.20/arch/arm/lib/udivdi3.c
+@@ -0,0 +1,246 @@
++/* More subroutines needed by GCC output code on some machines. */
++/* Compile this one with gcc. */
++/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
-+ ldr r12,=pmu_base
-+ ldr r12, [r12,#0]
-+
-+ /*Store the jump back address at this location (physical Address) */
-+ ldr r0, =backup_ram_base
-+ ldr r0, [r0,#0]
++This file is part of GNU CC.
+
-+ ldr r1, =after_deep_sleep
-+ mov r2, #0xC0000000
-+ sub r1, r1, r2 /* Change from VA to PA */
-+
-+ str r1, [r0]
-+
-+ /*Enter FIQ mode-Interrupt disabled and save the banked registers*/
-+ orr r0,r7,#0x1
-+ msr cpsr_cxsf,r0
-+
-+ mrs r0,spsr
-+ stmfd r6!, {r0,r8-r14} /* store r8 to r14 and spsr */
-+
-+ /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
-+ orr r0,r7,#0x2
-+ msr cpsr_cxsf,r0 /* enter IRQ mode with IRQ/FIQ disable */
-+
-+ mrs r0,spsr
-+ stmfd r6!, {r0,r13,r14}
-+
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
+
-+ /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
-+ orr r0,r7,#0x7
-+ msr cpsr_cxsf,r0
-+
-+ mrs r0,spsr
-+ stmfd r6!, {r0,r13,r14}
-+
-+
-+ /*Enter Undef Mode-IRQ/FIQ disable. Save r13,r14 and spsr */
-+ orr r0,r7,#0xB
-+ msr cpsr_cxsf,r0
-+
-+ mrs r0,spsr
-+ stmfd r6!, {r0,r13,r14}
-+
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
+
-+ /*Store the top of stack [VA] in the Scratch-Pad Register*/
-+ str r6,[r12,#0x14]
-+
-+ /*Go back in SVC mode*/
-+ orr r0,r7,#0x3
-+ msr cpsr_cxsf,r0
-+
-+ /* Store MMU registers */
-+ /*Domain Register on Back-up RAM structure*/
-+ mrc p15,0,r0,c3,c0,0
-+ str r0,[r8]
-+
-+ /*TTB Register*/
-+ mrc p15,0,r0,c2,c0,0
-+ str r0,[r8,#0x4]
-+
-+ /*MMU Enable Register*/
-+ mrc p15,0,r0,c1,c0,0
-+ str r0,[r8,#0x8]
-+
-+ /* Virtual Address of MMU Enable*/
-+ adr r0,mmu_enabled
-+ str r0,[r8,#0xC]
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
+
++/* As a special exception, if you link this library with other files,
++ some of which are compiled with GCC, to produce an executable,
++ this library does not by itself cause the resulting executable
++ to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License.
++ */
++/* support functions required by the kernel. based on code from gcc-2.95.3 */
++/* I Molton 29/07/01 */
+
-+ /*Clear the Remap bit from SRC-Register*/
-+ ldr r0,[r11]
-+ bic r0,r0,#0x100
-+ str r0,[r11]
-+
-+ /*Enable the Mode Status Register*/
-+ mov r0,#0
-+ str r0,[r11,#0x8]
-+
-+ /* Clear the PMU bit - for entering the deep sleep mode instead sleep*/
-+ ldr r0,[r12]
-+ bic r0,r0,#0x10
-+ str r0,[r12]
-+
-+ /*Store the value of Scratch-Pad Register*/
-+ ldr r0,=backup_ram_base_phys
-+ ldr r0,[r0,#0x0]
-+ str r0,[r12,#0x10]
-+
-+ /*Program to wake-up in Normal mode*/
-+ ldr r0,[r11,#0x4]
-+ bic r0,r0,#0xf
-+ orr r0,r0,#0x9
-+ str r0,[r11,#0x4]
++#include "gcclib.h"
++#include "longlong.h"
+
-+ /*Clean entire DCache using test and clean*/
-+clean_dcache:
-+ mrc p15,0,r15,c7,c10,3
-+ bne clean_dcache
-+
-+ /*Drain Write Buffers*/
-+ mov r0,#0
-+ mcr p15,0,r0,c7,c10,4
++const UQItype __clz_tab[] =
++{
++ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
++ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++};
+
-+ ldr r0, =L2dummyPointer
-+ ldr r0, [r0]
-+ mov r1, #0
-+ cmp r1, r0
-+ stmneia r0!,{r1-r8}
++UDItype
++__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
++{
++ DIunion ww;
++ DIunion nn, dd;
++ DIunion rr;
++ USItype d0, d1, n0, n1, n2;
++ USItype q0, q1;
++ USItype b, bm;
+
-+#ifdef CONFIG_L2CACHE_ENABLE
-+ v_l2_cache_clean_and_invalidate r0, r1
-+ v_l2_cache_sync r0, r1
-+ v_l2_cache_disable r0,r1
++ nn.ll = n;
++ dd.ll = d;
+
-+#endif
++ d0 = dd.s.low;
++ d1 = dd.s.high;
++ n0 = nn.s.low;
++ n1 = nn.s.high;
+
++ if (d1 == 0)
++ {
++ if (d0 > n1)
++ {
++ /* 0q = nn / 0D */
+
-+ /* Prefetch certain instructions in the cache. */
-+ adr r4, cache_prefetch_start
-+ adr r5, cache_prefetch_end
-+ mvn r1,#0x1F
-+ ands r4,r1,r4
-+fetch_loop:
-+ mcr p15, 0, r4, c7, c13,1
-+ cmp r4,r5
-+ addls r4, r4, #0x20
-+ bls fetch_loop
++ count_leading_zeros (bm, d0);
+
-+
-+cache_prefetch_start:
-+ ldr r10, =mpmc_base
-+ ldr r10,[r10,#0x0]
-+
-+/* Check sdram is idle */
-+poll_loop:
-+ ldr r1,[r10, #0x4]
-+ ands r1,r1,#0x1
-+ cmp r1,#0
-+ bne poll_loop
++ if (bm != 0)
++ {
++ /* Normalize, i.e. make the most significant bit of the
++ denominator set. */
+
-+ /*Put SDRAM in self-refresh mode*/
-+ ldr r1,[r10, #0x20]
-+ bic r1,r1,#0x1
-+ orr r1,r1,#0x04
-+ str r1,[r10, #0x20]
++ d0 = d0 << bm;
++ n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
++ n0 = n0 << bm;
++ }
+
-+ /*Wait for SDRAM to go in self-refresh*/
-+wait:
-+ ldr r1,[r10,#0x4]
-+ and r1,r1,#0x4
-+ cmp r1,#0x0
-+ beq wait
++ udiv_qrnnd (q0, n0, n1, n0, d0);
++ q1 = 0;
+
++ /* Remainder in n0 >> bm. */
++ }
++ else
++ {
++ /* qq = NN / 0d */
+
++ if (d0 == 0)
++ d0 = 1 / d0; /* Divide intentionally by zero. */
+
++ count_leading_zeros (bm, d0);
+
-+ /*Move system to sleep mode*/
-+ ldr r1,[r11]
-+ bic r1, r1, #0x7
-+ str r1,[r11]
++ if (bm == 0)
++ {
++ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
++ conclude (the most significant bit of n1 is set) /\ (the
++ leading quotient digit q1 = 1).
+
-+goto_sleep:
-+ ldr r1,[r11]
-+ and r1,r1,#0x78
-+ cmp r1,#0x0
-+ bne goto_sleep
++ This special case is necessary, not an optimization.
++ (Shifts counts of SI_TYPE_SIZE are undefined.) */
+
-+
-+ nop
-+ nop
-+ nop
-+ nop
++ n1 -= d0;
++ q1 = 1;
++ }
++ else
++ {
++ /* Normalize. */
+
++ b = SI_TYPE_SIZE - bm;
+
++ d0 = d0 << bm;
++ n2 = n1 >> b;
++ n1 = (n1 << bm) | (n0 >> b);
++ n0 = n0 << bm;
+
++ udiv_qrnnd (q1, n1, n2, n1, d0);
++ }
+
-+/* For deepsleep this much pre-fetch is enough */
-+cache_prefetch_end:
-+ mov r0, r0
-+ mov r0, r0
-+ mov r0, r0
-+ mov r0, r0
++ /* n1 != d0... */
+
++ udiv_qrnnd (q0, n0, n1, n0, d0);
+
-+after_deep_sleep:
-+/* Restore the MMU registers */
++ /* Remainder in n0 >> bm. */
++ }
++
++ if (rp != 0)
++ {
++ rr.s.low = n0 >> bm;
++ rr.s.high = 0;
++ *rp = rr.ll;
++ }
++ }
++ else
++ {
++ if (d1 > n1)
++ {
++ /* 00 = nn / DD */
+
-+
++ q0 = 0;
++ q1 = 0;
+
-+ ldr r8,=backup_ram_store_phys
-+ mov r9, #0xC0000000
-+ sub r8, r8, r9 /* Change from VA to PA */
-+ ldr r8, [r8,#0]
++ /* Remainder in n1n0. */
++ if (rp != 0)
++ {
++ rr.s.low = n0;
++ rr.s.high = n1;
++ *rp = rr.ll;
++ }
++ }
++ else
++ {
++ /* 0q = NN / dd */
+
++ count_leading_zeros (bm, d1);
++ if (bm == 0)
++ {
++ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
++ conclude (the most significant bit of n1 is set) /\ (the
++ quotient digit q0 = 0 or 1).
+
++ This special case is necessary, not an optimization. */
+
-+out_of_sleep:
-+ /*Domain Register*/
-+ ldr r0,[r8, #0x0]
-+ mcr p15,0,r0,c3,c0,0
-+
-+ /*TTB Register*/
-+ ldr r0,[r8,#0x4]
-+ mcr p15,0,r0,c2,c0,0
++ /* The condition on the next line takes advantage of that
++ n1 >= d1 (true due to program flow). */
++ if (n1 > d1 || n0 >= d0)
++ {
++ q0 = 1;
++ sub_ddmmss (n1, n0, n1, n0, d1, d0);
++ }
++ else
++ q0 = 0;
+
++ q1 = 0;
+
-+ /* Virtual Address of mmu_enabled*/
-+ ldr r4, [r8, #0xC]
++ if (rp != 0)
++ {
++ rr.s.low = n0;
++ rr.s.high = n1;
++ *rp = rr.ll;
++ }
++ }
++ else
++ {
++ USItype m1, m0;
++ /* Normalize. */
+
-+ /*MMU Enable Register*/
-+ ldr r1, [r8,#0x8]
-+ mcr p15,0,r1,c1,c0,0
++ b = SI_TYPE_SIZE - bm;
+
-+ mov pc,r4
-+ mov r0, r0
-+ mov r0, r0
-+ mov r0, r0
-+ mov r0, r0
-+
++ d1 = (d1 << bm) | (d0 >> b);
++ d0 = d0 << bm;
++ n2 = n1 >> b;
++ n1 = (n1 << bm) | (n0 >> b);
++ n0 = n0 << bm;
+
++ udiv_qrnnd (q0, n1, n2, n1, d1);
++ umul_ppmm (m1, m0, q0, d0);
+
-+mmu_enabled:
++ if (m1 > n1 || (m1 == n1 && m0 > n0))
++ {
++ q0--;
++ sub_ddmmss (m1, m0, m1, m0, d1, d0);
++ }
+
-+#ifdef DEEP_SLEEP_DEBUG
-+ ldr r9, =uart1_base
-+ ldr r9, [r9,#0]
++ q1 = 0;
++
++ /* Remainder in (n1n0 - m1m0) >> bm. */
++ if (rp != 0)
++ {
++ sub_ddmmss (n1, n0, n1, n0, m1, m0);
++ rr.s.low = (n1 << b) | (n0 >> bm);
++ rr.s.high = n1 >> bm;
++ *rp = rr.ll;
++ }
++ }
++ }
++ }
++
++ ww.s.low = q0;
++ ww.s.high = q1;
++ return ww.ll;
++}
++
++UDItype
++#ifdef CONFIG_AEABI
++__aeabi_uldivmod (UDItype n, UDItype d)
++#else
++__udivdi3 (UDItype n, UDItype d)
+#endif
++{
++ return __udivmoddi4 (n, d, (UDItype *) 0);
++}
+
-+ ldr r11, =src_base
-+ ldr r11, [r11,#0]
-+ ldr r12, =pmu_base
-+ ldr r12, [r12,#0]
-+ ldr r10, =mpmc_base
-+ ldr r10, [r10,#0]
++UDItype
++__umoddi3 (UDItype u, UDItype v)
++{
++ UDItype w;
+
++ (void) __udivmoddi4 (u ,v, &w);
+
++ return w;
++}
+
-+ /* Move system to Normal Mode */
-+ ldr r1,[r11]
-+ orr r1,r1,#0x4
-+ bic r1,r1,#0x3
-+ str r1,[r11]
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik
+@@ -0,0 +1,267 @@
++if ARCH_NOMADIK
+
++# The GPIO_PIN_23 is shared between MMC and MSP0.
++# by default this pin is used for MMC for NOMADIK_NDK15_REV2_B_03 target
++# to use this pin for MSP it should be configured 'n'
++config NOMADIK_NDK15_REV2_MMC
++ bool
++ default y if NOMADIK_NDK15_REV2_B_03
+
-+ /*Wait for the system to move in normal mode*/
-+wait_norm1:
-+ ldr r0,[r11, #0x0]
-+ and r0,r0,#0x78
-+ cmp r0, #0x20
-+ bne wait_norm1
++config NOMADIK_NDK10_CUTA
++ bool
++ default y if NOMADIK_NDK10_CUT_A1
+
-+
-+ /* Remove the chip from Interrupt mode */
-+ ldr r0,[r11, #0x4]
-+ bic r0,r0,#0x1
-+ str r0,[r11, #0x4]
++config NOMADIK_NDK10_CUTB
++ bool
++ default y if (NOMADIK_NDK10_CUT_B0 || NOMADIK_NDK10_CUT_B06)
+
-+ /* Clear the interrupt mode status bit*/
-+ mov r0, #0x0
-+ str r0, [r11, #0x8]
++config NOMADIK_GPIO
++ bool
++ default y
+
-+ /* For CLCD Refresh issue */
-+ ldr r1, =0x00000005 /* Loading the value with timeout so as to avoid flickering on CLCD */
-+ str r1, [r10, #0x408]
++config NOMADIK_ENABLE_L2CACHE
++ bool "Enable L2 Cache controller"
++ depends on (NOMADIK_NDK15 || NOMADIK_NHK15)
++ default y if NOMADIK_STN8815CAS22H11
++ select L2CACHE_ENABLE
++ help
++ Nomadik Chip version for this platfrom supports L2 Cache
++ by default it is enabled, if you want to check system
++ performanence without L2 Cache, then say no here
+
++config GPIO_PROC
++ bool
++ default y
++ depends on NOMADIK_GPIO
+
-+ /* Stack Restoration Routine */
-+ ldr r6,[r12,#0x14]
++config NOMADIK_DMA
++ tristate "NOMADIK DMA SUPPORT"
++ depends on ISA_DMA_API
++ default y
++ help
++ Nomadik DMA low level driver for standrd DMA interface
+
-+ /* Store the value of cpsr in r7*/
-+ mrs r7,cpsr
-+ orr r7,r7,#0xC0 /*Not Needed*/
-+ bic r7,r7,#0xf
-+
-+ /*Move to undef mode and restore everything*/
-+ orr r0,r7,#0xB
-+ msr cpsr_cxsf,r0
-+
-+ ldmfd r6!, {r0,r13,r14}
-+ msr spsr_cxsf,r0
-+
-+ /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
-+ orr r0,r7,#0x7
-+ msr cpsr_cxsf,r0
-+
-+ ldmfd r6!, {r0,r13,r14}
-+ msr spsr_cxsf,r0
-+
-+ /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
-+ orr r0,r7,#0x2
-+ msr cpsr_cxsf,r0
-+
-+ ldmfd r6!, {r0,r13,r14}
-+ msr spsr_cxsf,r0
-+
-+
-+ /*Enter FIQ mode-Interrupt disabled and save the banked registers. Save: r8-r14 and spsr*/
-+ orr r0,r7,#0x1
-+ msr cpsr_cxsf,r0
-+
-+ ldmfd r6!, {r0,r8-r14}
-+ msr spsr_cxsf,r0
-+
-+ /* Here we will restore our cpsr..IRQ/FIQ Disabled*/
-+ ldr r0, [r6]
-+ msr cpsr_cxsf, r0
-+ add r6, r6,#4
-+
-+ /*Now only two user-mode registers are left*/
-+ ldmia r6,{sp, lr}^
-+ mov r0,r0
-+ add r6,r6,#8
-+
-+ /*Restore sp*/
-+ mov sp,r6
-+
-+
-+ /*ReStore the remaining items*/
-+ ldmfd sp!, {r0-r9}
-+
-+ mcr p15,0, r0,c5,c0,0 /*FSR--Domain Fault */
-+ mcr p15,0, r1,c5,c0,1 /*FSR--Instruction Fault */
++config NOMADIK_SSP
++ tristate "NOMADIK SSP SUPPORT"
++ depends on (NOMADIK_DMA && NOMADIK_SPI)
++ default m
++ help
++ Depends on Nomadik DMA driver and SPI driver
+
-+ mcr p15,0, r2,c6,c0,0 /* FAR */
-+
-+ mcr p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
-+ mcr p15,0, r4,c9,c0,1 /* Read ICache Lockdown */
-+
-+ mcr p15,0, r5,c9,c1,0 /* Read Data TLB */
-+ mcr p15,0, r6,c9,c1,1 /* Read Instruction Lockdown */
-+
-+ mcr p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
-+
-+ mcr p15,0, r8,c13,c0,0 /* FCSE--PID */
-+ mcr p15,0, r9,c13,c0,1 /* Context-ID */
++config NOMADIK_MSP
++ tristate "NOMADIK MSP SUPPORT"
++ depends on (NOMADIK_DMA && NOMADIK_SPI)
++ default m
++ help
++ Depends on Nomadik DMA driver and SPI driver
+
++config NOMADIK_MTU
++ tristate "NOMADIK MTU SUPPORT"
++ default m
++ help
++ The driver offers 8 MTU units tobe used.
++ In case of module only MTU1 unit will be
++ available with 4 timers:
++ MTU1_T0, MTU1_T1, MTU1_T2 & MTU1_T3
+
-+
++config NOMADIK_MTU_SYSTEM_TICK
++ bool "NOMADIK MTU SYSTEM TICK SUPPORT"
++ depends on NOMADIK_MTU
++ help
++ This will prevent the system tick to be used through MTU.
++ default y
+
++config NOMADIK_RTC
++ bool "NOMADIK RTC/RTT SUPPORT"
++ default y
++ help
++ The driver offers RTC and RTT support.
++ The RTC can be used through /dev/rtc interface for real
++ time calculations, alarms, long delays if required
++ If unsure say Y here.
+
++config NOMADIK_PM
++ bool "NOMADIK POWER MANAGEMENT SUPPORT"
++ depends on ( (NOMADIK_NHK15 || NOMADIK_NDK15) && NOMADIK_RTC )
++ default y
++ select PM if NOMADIK_PM
++ help
++ Nomadik Power Management Driver
+
-+ /* ReStoring the enabled values of VIC */
-+ ldr r0, =vic_base
-+ ldr r0, [r0,#0]
++config NOMADIK_SVA_INIT_MEM
++ bool "NOMADIK SVA MEMORY at initialisation"
++ default n
++ help
++ The driver uses physically contiguous memory allocated
++ at kernel initialisation time.
++ If unsure say N here.
+
-+ ldmfd sp!,{r1-r10}
-+ str r1,[r0,#0x218]
-+ str r2,[r0,#0x21C]
-+ str r3,[r0,#0x220]
-+ str r4,[r0,#0x224]
-+ str r5,[r0,#0x228]
-+ str r6,[r0,#0x22C]
-+ str r7,[r0,#0x230]
-+ str r8,[r0,#0x234]
-+ str r9,[r0,#0x238]
-+ str r10,[r0,#0x23C]
++config FORCE_MAX_ZONEORDER
++ int "Maximum zone order"
++ default "13"
++ help
++ For use cases having large memory requirements choosing a
++ larger memory size is advised.
+
++config NOMADIK_SVA_MEM_SIZE
++ int "SVA initial memory size" if NOMADIK_SVA_INIT_MEM
++ default "4"
++ help
++ For use cases having large memory requirements choosing a
++ larger memory size is advised.
+
-+ ldmfd sp!,{r1-r11}
-+ str r1,[r0,#0x12C]
-+ str r2,[r0,#0x130]
-+ str r3,[r0,#0x134]
-+ str r4,[r0,#0x138]
-+ str r5,[r0,#0x13C]
-+ str r6,[r0,#0x200]
-+ str r7,[r0,#0x204]
-+ str r8,[r0,#0x208]
-+ str r9,[r0,#0x20C]
-+ str r10,[r0,#0x210]
-+ str r11,[r0,#0x214]
++config NOMADIK_SVA_VPIP
++ bool "NOMADIK SVA VPIP support"
++ default y
++ help
++ This enables the support for VPIP in SVA driver. This allows to
++ create IRP services in SVA to grab the images from sensor CCP0.
++ Warning: This disables Ethernet & MTD devices.
+
++config NOMADIK_SAA_INIT_MEM
++ bool "NOMADIK SAA MEMORY at initialisation"
++ default n
++ help
++ The SAA driver uses physically contiguous memory allocated
++ at kernel initialisation time.
++ If unsure say N here.
+
++#Configuration for default display setup
++choice
++ prompt "Default Display Type"
++ depends on FB
++ default FB_NOMADIK_QVGA_PORTRAIT
+
-+ ldmfd sp!,{r1-r11}
-+ str r1,[r0,#0x100]
-+ str r2,[r0,#0x104]
-+ str r3,[r0,#0x108]
-+ str r4,[r0,#0x10C]
-+ str r5,[r0,#0x110]
-+ str r6,[r0,#0x114]
-+ str r7,[r0,#0x118]
-+ str r8,[r0,#0x11C]
-+ str r9,[r0,#0x120]
-+ str r10,[r0,#0x124]
-+ str r11,[r0,#0x128]
++config FB_NOMADIK_VGA
++ bool "CLCD VGA"
+
-+ ldmfd sp!, {r1-r5}
-+ str r1, [r0,#0xC] /* Interrupt sslection register */
-+ str r2, [r0, #0x2C]
-+ str r3, [r0, #0x10] /* Interrupt Enable register */
-+ str r4, [r0, #0x30]
-+ str r5, [r0, #0x54] /* Default VAR */
-+
++config FB_NOMADIK_CRT
++ bool "CRT VGA"
+
++config FB_NOMADIK_QVGA_PORTRAIT
++ bool "CLCD QVGA Portrait"
+
-+ /*Clean entire DCache using test and clean*/
-+clean_dcache_end:
-+ mrc p15,0,r15,c7,c14,3
-+ bne clean_dcache_end
++config FB_NOMADIK_QVGA_LANDSCAPE
++ bool "CLCD QVGA Landscape"
+
-+
-+ /* Invalidate I cache and Dcache */
-+ mov r0,#0
-+ mcr p15,0,r0,c7,c7,0
++config FB_NOMADIK_WVGA
++ bool "CLCD WVGA"
++endchoice
+
-+ /*Drain Write Buffers*/
-+ mov r0,#0
-+ mcr p15,0,r0,c7,c10,4
++choice
++ prompt "Default Display BPP"
++ depends on FB
++ default FB_NOMADIK_PANEL_24BPP_PACKED
+
-+ mov r0,#0
-+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs
++config FB_NOMADIK_PANEL_8BPP
++ bool "8 BPP"
+
-+ mov r0,#0
-+ mov r0,#0
-+ mov r0,#0
-+ mov r0,#0
++config FB_NOMADIK_PANEL_16BPP
++ bool "16 BPP"
+
++config FB_NOMADIK_PANEL_24BPP
++ bool "24 BPP"
+
-+#ifdef DEEP_SLEEP_DEBUG
-+ ldr r0, =uart1_base
-+ ldr r0, [r0,#0x0]
-+ mov r1, #0x65
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+ mov r1, #0x66
-+ str r1, [r0]
-+#endif
-+
-+
-+/*Try to go back also...FIQ Disabled...IRQ Disabled*/
-+ ldmfd sp!,{r0-r12,pc}
++config FB_NOMADIK_PANEL_24BPP_PACKED
++ bool "24 BPP Packed"
+
++endchoice
+
-+uart1_phys:
-+ .word 0x101FB000
-+src_phys:
-+ .word 0x101E0000
-+backup_ram_store_phys:
-+ .word 0x80010250
-+mtu0_base:
-+ .word 0xf01E2000
++config FB_NOMADIK_ACCLN
++ bool "Nomadik Graphics Acceleration"
++ tristate
++ depends on FB
++ default y
++ help
++ enable hw accln for graphics on nomadik
+
-+uart1_base:
-+ .word 0xf01FB000
-+src_base:
-+ .word 0xf01E0000
-+pmu_base:
-+ .word 0xf01E9000
-+fsmc_base:
-+ .word 0xf0100000
-+backup_ram_base_phys:
-+ .word 0x80010000
-+vic_base:
-+ .word 0xf0140000
-+mpmc_base:
-+ .word 0xf0110000
-+backup_ram_store:
-+ .word 0x80010250
-+backup_ram_base:
-+ .word 0x80010000
-+.end
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/dfs.S ../new/linux-2.6.20/arch/arm/mach-nomadik/dfs.S
---- linux-2.6.20/arch/arm/mach-nomadik/dfs.S 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/dfs.S 2008-07-28 15:20:41.000000000 +0530
-@@ -0,0 +1,355 @@
-+/*
-+ * arch/arm/mach-nomadik/sleep.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Low-level Nomadik DFS support
-+ */
++config FB_NOMADIK_PANEL_BPP
++ int
++ default 16 if !FB
++ default 8 if FB_NOMADIK_PANEL_8BPP
++ default 16 if FB_NOMADIK_PANEL_16BPP
++ default 24 if FB_NOMADIK_PANEL_24BPP_PACKED
++ default 32 if FB_NOMADIK_PANEL_24BPP
+
-+.align 5
-+.globl dfs
++config FB_NOMADIK_PANEL_NAME
++ string
++ default "VGA" if !FB
++ default "VGA" if FB_NOMADIK_VGA
++ default "CRT" if FB_NOMADIK_CRT
++ default "QVGA_Portrait" if FB_NOMADIK_QVGA_PORTRAIT
++ default "QVGA_Landscape" if FB_NOMADIK_QVGA_LANDSCAPE
++ default "WVGA" if FB_NOMADIK_WVGA
+
++config FB_NOMADIK_PANEL_XRES
++ int
++ default 800 if FB_NOMADIK_WVGA
++ default 640 if !FB
++ default 640 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT)
++ default 240 if FB_NOMADIK_QVGA_PORTRAIT
++ default 320 if FB_NOMADIK_QVGA_LANDSCAPE
+
-+dfs:
-+ stmfd sp!,{r4-r12,lr}
++config FB_NOMADIK_PANEL_YRES
++ int
++ default 480 if !FB
++ default 480 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT || FB_NOMADIK_WVGA)
++ default 320 if FB_NOMADIK_QVGA_PORTRAIT
++ default 240 if FB_NOMADIK_QVGA_LANDSCAPE
+
-+ str r3, bkup_adr_base
-+ add r4, r3, #8
-+ str r4, bkup_adr
-+ add r4, r3, #0x1c8
-+ str r4, bkup_data
-+ add r4, r3, #0x388
-+ str r4, bkup_action
-+ add r4, r3, #0x3f8
-+ str r4, bkup_size
++config FB_NOMADIK_PANEL_LFMARGIN
++ hex
++ default 0xD6 if FB_NOMADIK_WVGA
++ default 0x21 if !FB
++ default 0x21 if FB_NOMADIK_VGA
++ default 0x29 if FB_NOMADIK_CRT
++ default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
-+ ldr r9, bkup_size
-+ ldr r9,[r9]
-+ ldr r10,bkup_adr
-+ ldr r11,bkup_data
-+ ldr r12,bkup_action
++config FB_NOMADIK_PANEL_RTMARGIN
++ hex
++ default 0x27 if FB_NOMADIK_WVGA
++ default 0x40 if !FB
++ default 0x40 if FB_NOMADIK_VGA
++ default 0x09 if FB_NOMADIK_CRT
++ default 0x2f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
-+ mrc p15, 0, r3, c10, c0, 0 /* read the lockdown register */
-+ orr r3, r3, #1 /* set the preserved bit */
-+ mcr p15, 0, r3, c10, c0, 0 /* write to the lockdown register */
-+
++config FB_NOMADIK_PANEL_UPRMARGIN
++ hex
++ default 0x22 if FB_NOMADIK_WVGA
++ default 0x07 if !FB
++ default 0x07 if FB_NOMADIK_VGA
++ default 0x19 if FB_NOMADIK_CRT
++ default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
++config FB_NOMADIK_PANEL_LWRMARGIN
++ hex
++ default 0xA if FB_NOMADIK_WVGA
++ default 0x24 if !FB
++ default 0x24 if FB_NOMADIK_VGA
++ default 0x02 if FB_NOMADIK_CRT
++ default 0x0f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
++config FB_NOMADIK_PANEL_HSLEN
++ hex
++ default 0x1 if FB_NOMADIK_WVGA
++ default 0x40 if !FB
++ default 0x40 if FB_NOMADIK_VGA
++ default 0x61 if FB_NOMADIK_CRT
++ default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
-+ ldr r4, mpmc_base
-+ mcr p15, 0, r4, c8, c7, 1
-+ ldr r4, [r4]
-+ mrc p15, 0, r3, c10, c0, 0
-+
-+
-+ ldr r4, src_base
-+ mcr p15, 0, r4, c8, c7, 1
-+ ldr r4, [r4]
-+ mrc p15, 0, r3, c10, c0, 0
-+
-+ ldr r4, bkup_adr_base
-+ mcr p15, 0, r4, c8, c7, 1
-+ ldr r4, [r4]
-+ mrc p15, 0, r3, c10, c0, 0
-+
-+
-+ bic r3, r3, #1 /* clear preserve bit */
-+ mcr p15, 0, r3, c10, c0, 0 /* write to the lockdown register */
-+
-+ ldr r7,mpmc_base
-+ ldr r8,src_base
++config FB_NOMADIK_PANEL_VSLEN
++ hex
++ default 0x1 if FB_NOMADIK_WVGA
++ default 0x19 if !FB
++ default 0x19 if FB_NOMADIK_VGA
++ default 0x02 if FB_NOMADIK_CRT
++ default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
-+/*
-+ mov r7, #0xf0
-+ lsl r7, #8
-+ orr r7, r7, #0x11
-+ lsl r7, #16
++config FB_NOMADIK_PANEL_TIM2VAL
++ hex
++ default 0x031f1822 if FB_NOMADIK_WVGA
++ default 0x027f1800 if !FB
++ default 0x027f1800 if (FB_NOMADIK_VGA)
++ default 0x027f3800 if (FB_NOMADIK_CRT)
++ default 0x00ef1804 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++#Configuration for default display setup ends here
+
-+ mov r8, #0xf0
-+ lsl r8, #8
-+ orr r8, r8, #0x1e
-+ lsl r8, #16
-+*/
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/Makefile
+@@ -0,0 +1,166 @@
++#
++# Makefile for the linux kernel.
++#
+
++ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
++include $(TOPDIR)/.config
++endif
+
-+ /* Prefetch certain instructions in the cache. */
-+ adr r4, cache_prefetch_start1
-+ adr r5, cache_prefetch_end1
-+ mvn r3,#0x1F
-+ ands r4,r3,r4
-+fetch_loop:
-+ mcr p15, 0, r4, c7, c13,1
-+ cmp r4,r5
-+ addls r4, r4, #0x20
-+ bls fetch_loop
++# Object file lists.
+
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
++TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
++SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
++PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
++NMDK_EXTRA_CFLAGS = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
+
++EXTRA_CFLAGS-y := $(NMDK_EXTRA_CFLAGS)
++EXTRA_CFLAGS-$(CONFIG_NOMADIK_MTU) += -DCONFIG_MTU0
++CFLAGS += $(EXTRA_CFLAGS-y)
+
-+cache_prefetch_start1:
-+
-+ /**
-+ *Put SDRAM in self-refresh mode
-+ */
-+ ldr r3,[r7, #0x20]
-+ orr r3,r3,#0x04
-+ str r3,[r7, #0x20]
++# NMDKDBG_FLAGS maintainence for all Nomadik debuging strategy
++# Add new entry for new component to be supported here
++NMDKDBG_FLAGS :=
+
++ifdef VIC_DEBUG
++NMDKDBG_FLAGS += -DVIC_DEBUG=$(VIC_DEBUG)
++endif
+
-+ /**
-+ *Wait for SDRAM to go in self-refresh
-+ */
-+wait_till_selfrefresh :
-+ ldr r3,[r7,#0x4]
-+ and r3,r3,#0x4
-+ cmp r3,#0x0
-+ beq wait_till_selfrefresh
++ifdef RTC_DEBUG
++NMDKDBG_FLAGS += -DRTC_DEBUG=$(RTC_DEBUG)
++endif
+
++ifdef GPIO_DEBUG
++NMDKDBG_FLAGS += -DGPIO_DEBUG=$(GPIO_DEBUG)
++endif
+
-+ /**
-+ * Stop the DLL, leave SDMC on
-+ */
-+ ldr r3,[r7]
-+ bic r3,r3,#0x2
-+ str r3,[r7]
++ifdef DMA_DEBUG
++NMDKDBG_FLAGS += -DDMA_DEBUG=$(DMA_DEBUG)
++endif
+
-+ /**
-+ *Move the system in Slow mode
-+ */
-+ ldr r3,[r8]
-+ bic r3,r3,#0x7
-+ orr r3,r3,#0x2
-+ str r3,[r8]
++ifdef EPIO_DEBUG
++NMDKDBG_FLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG)
++endif
+
-+wait_till_slow_mode:
-+ ldr r3,[r8]
-+ and r3,r3,#0x78
-+ cmp r3,#0x10
-+ bne wait_till_slow_mode
-+
-+ ldr r3,[r8]
-+ bic r3,r3,#0x6000
-+ orr r3,r3,r2,LSL #13
-+ str r3,[r8]
++ifdef SPI_DEBUG
++NMDKDBG_FLAGS += -DSPI_DEBUG=$(SPI_DEBUG)
++endif
+
-+ ldr r3,[r8,#0x14]
-+ bic r3,r3,#0x3F00
-+ bic r3,r3,#0x7
-+ orr r3,r3,r0
-+ orr r3,r3,r1,LSL #8
-+ str r3,[r8,#0x14]
-+
-+ /**
-+ *Move the system in Normal mode
-+ */
-+ ldr r0,[r8, #0x0]
-+ ldr r1, =0xfffffff8
-+ and r0,r0,r1
-+ orr r0,r0,#0x4
-+ str r0,[r8, #0x0]
-+
-+wait_till_normal_mode:
-+ ldr r0,[r8, #0x0]
-+ and r0,r0,#0x78
-+ cmp r0, #0x20
-+ bne wait_till_normal_mode
-+
-+
-+#define ACTION_WRITE 0x01
-+#define ACTION_WRITE_AND 0x02
-+#define ACTION_WRITE_OR 0x03
-+#define ACTION_READ 0x04
-+#define ACTION_POLL 0x05
-+#define ACTION_POLL_AND 0x06
-+#define ACTION_POLL_OR 0x07
-+#define ACTION_WAIT 0x08
-+
-+/*
-+ ldr r12,bkup_size
-+ ldr r9,[r12]
-+
-+ ldr r10,bkup_adr
-+ ldr r11,bkup_data
-+ ldr r12,bkup_action
-+*/
-+
-+
-+ mov r8,#0x0
-+loop1:
-+ cmp r8,r9
-+ beq end1
-+
-+ ldr r7,[r10]
-+ ldr r6,[r11]
-+ ldr r5,[r12]
++ifdef SSP_DEBUG
++NMDKDBG_FLAGS += -DSSP_DEBUG=$(SSP_DEBUG)
++endif
+
-+ mov r2,r8
-+ and r2,r2,#0x3
-+ mov r2,r2,LSL #0x3
-+ mov r5,r5,LSR r2
-+ and r5,r5,#0xFF
++ifdef MSP_DEBUG
++NMDKDBG_FLAGS += -DMSP_DEBUG=$(MSP_DEBUG)
++endif
+
-+
-+ /**
-+ Decide action to be taken
-+ */
-+ ldr r4,=ACTION_WRITE
-+ cmp r5,r4
-+ beq action_write
-+ ldr r4,=ACTION_WRITE_AND
-+ cmp r5,r4
-+ beq action_write_and
-+ ldr r4,=ACTION_WRITE_OR
-+ cmp r5,r4
-+ beq action_write_or
-+ ldr r4,=ACTION_READ
-+ cmp r5,r4
-+ beq action_read
-+ ldr r4,=ACTION_POLL
-+ cmp r5,r4
-+ beq action_poll
-+ ldr r4,=ACTION_POLL_AND
-+ cmp r5,r4
-+ beq action_poll_and
-+ ldr r4,=ACTION_POLL_OR
-+ cmp r5,r4
-+ beq action_poll_or
-+ ldr r4,=ACTION_WAIT
-+ cmp r5,r4
-+ beq action_wait
-+ b action_end
-+action_write:
-+#if 0
-+ mov r4, #0xf0
-+ lsl r4, #8
-+ orr r4, #0x1f
-+ lsl r4, #8
-+ orr r4, #0xb0
-+ lsl r4, #8
++ifdef KEYPAD_DEBUG
++NMDKDBG_FLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG)
++endif
+
-+ mov r3, #0x73
-+ str r3, [r4]
-+#endif
-+ str r6,[r7]
-+ b action_end
-+action_write_and:
++ifdef TOUCHP_DEBUG
++NMDKDBG_FLAGS += -DTOUCHP_DEBUG=$(TOUCHP_DEBUG)
++endif
+
-+ b action_end
-+action_write_or:
-+ ldr r3,[r7]
-+ orr r3,r3,r6
-+ str r3,[r7]
-+ b action_end
-+action_read:
-+ ldr r3,[r7]
-+ b action_end
-+action_poll:
-+ b action_end
-+action_poll_and:
-+ b action_end
-+action_poll_or:
-+ b action_end
-+action_wait:
-+ cmp r6,#0x0
-+ beq action_end
-+ sub r6,r6,#0x1
-+ b action_wait
-+action_end:
-+
-+ add r10,r10,#0x4
-+ add r11,r11,#0x4
-+ /**
-+ * Determine if r8 is multiple of 4 and r12 must be increased
-+ */
-+ mov r2,r8
-+ and r2,r2,#0x3
-+ cmp r2,#0x3
-+ bne incr8
-+ add r12,r12,#0x4
-+incr8:
-+ add r8,r8,#0x01
-+ b loop1
-+end1:
++ifdef POWER_DEBUG
++NMDKDBG_FLAGS += -DPOWER_DEBUG=$(POWER_DEBUG)
++endif
+
-+ mov r10, #0xf0
-+ lsl r10, #8
-+ orr r10, r10, #0x11
-+ lsl r10, #16
++ifdef PM_DEBUG
++NMDKDBG_FLAGS += -DPM_DEBUG=$(PM_DEBUG)
++endif
+
++ifdef CPUFREQ_DEBUG
++NMDKDBG_FLAGS += -DCPUFREQ_DEBUG=$(CPUFREQ_DEBUG)
++endif
+
++ifdef SLEEP_DEBUG
++NMDKDBG_FLAGS += -DSLEEP_DEBUG=$(SLEEP_DEBUG)
++endif
+
++ifdef SVA_DEBUG
++NMDKDBG_FLAGS += -DSVA_DEBUG=$(SVA_DEBUG)
++endif
++#export the nomadik debug flags for driver/* build
++CFLAGS += $(NMDKDBG_FLAGS)
+
-+ ldr r1,[r10]
-+ orr r1,r1,#0x2
-+ str r1,[r10]
-+
-+ /* Wait for the DLL to lock */
-+waitlock:
-+ ldr r1,[r10,#0x4]
-+ and r1,r1,#0x8
-+ cmp r1,#0x0
-+ beq waitlock
-+
-+ /* Exit DDR-SDRAM from self-refresh mode */
-+ ldr r1,[r10, #0x20]
-+ bic r1,r1,#0x04
-+ str r1,[r10, #0x20]
++obj-y := gpio.o clock.o timer.o irq.o fsmc.o
+
-+ /* Wait for DDR-SDRAM to exit from self-refresh */
-+loop_refresh:
-+ ldr r1,[r10,#0x4]
-+ and r1,r1,#0x4
-+ cmp r1,#0x4
-+ beq loop_refresh
-+
++obj-y += $(SOC_NAME)_devices.o
++obj-y += $(PLATFORM_NAME)_devices.o
+
-+ ldmfd sp!,{r4-r12,pc}
++# Soc Specific modules
+
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
++obj-$(CONFIG_NOMADIK_PM) += sleep.o deep_sleep.o soft_sleep.o normal.o slow.o pm.o
+
-+cache_prefetch_end1 : /* This is the end of the code to be copied into eSRAM */
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
++ifeq ($(CONFIG_NOMADIK_PM),y)
++obj-y += power.o
++endif
+
-+bkup_adr_base :
-+ .word 0x80010000
-+bkup_adr :
-+ .word 0x80010008
-+bkup_data :
-+ .word 0x800101C8
-+bkup_action :
-+ .word 0x80010388
-+bkup_size :
-+ .word 0x800103F8
-+src_base :
-+ .word 0xf01E0000
-+mpmc_base :
-+ .word 0xf0110000
-+uart1_base :
-+ .word 0xf01fb000
-+
++ifeq ($(CONFIG_L2CACHE_ENABLE),y)
++obj-y += l2cc.o
++endif
++ifeq ($(CONFIG_CPU_FREQ_NOMADIK),y)
++obj-y += power.o slow.o
++endif
+
++obj-$(CONFIG_CPU_FREQ_NOMADIK) += cpu.o dfs.o
++obj-$(CONFIG_NOMADIK_DMA) += nmdkmod_DMA.o
++obj-$(CONFIG_NOMADIK_SSP) += nmdkmod_ssp.o
++obj-$(CONFIG_NOMADIK_MSP) += nmdkmod_msp.o
++obj-$(CONFIG_NOMADIK_MTU) += nmdkmod_mtu.o
++obj-$(CONFIG_NOMADIK_RTC) += nmdkmod_rtc.o
+
++nmdkmod_gpio-objs := gpio.o
++nmdkmod_DMA-objs := dma.o
++nmdkmod_ssp-objs := ssp.o
++nmdkmod_msp-objs := msp.o
++nmdkmod_mtu-objs := mtu.o
++nmdkmod_rtc-objs := rtc.o
+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/dma.c ../new/linux-2.6.20/arch/arm/mach-nomadik/dma.c
---- linux-2.6.20/arch/arm/mach-nomadik/dma.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/dma.c 2008-07-04 23:45:04.000000000 +0530
-@@ -0,0 +1,1337 @@
-+/*
-+ * arch/arm/mach-nomadik/dma.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Nomadik DMA driver to support standard APIs.
-+ * the API details can be found at ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
-+ *
-+ * Author : Prafulla WADASKAR <prafulla.wadaskar@st.com>
-+ */
-+#define DMA_VER "2.1.0"
++# Auto board configuration/dependency resolution
++#include $(TOPDIR)/.config
+
-+#include <linux/module.h> /* module functions */
-+#include <linux/slab.h>
-+#include <linux/mman.h>
-+#include <linux/init.h>
-+#include <linux/wait.h> /* For wait queues */
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/spinlock.h> /* spinlocks */
-+#include <linux/errno.h> /* err nos */
-+#include <linux/sched.h> /* wait macros */
-+#include <linux/mm.h> /* GFP flags */
-+#include <linux/amba/bus.h> /* Amba device register */
-+#include <linux/cpufreq.h>
-+#include <asm/page.h>
-+#include <asm/dma.h>
-+#include <asm/fiq.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h> /* for cli etc */
-+#include <asm/hardware.h>
-+#include <asm/hardware/iomd.h>
-+#include <asm/mach/dma.h>
-+#include <asm/mach/irq.h>
-+#include <asm/arch/defs.h>
-+#include <asm/arch/memory.h>
-+#include <asm/arch/debug.h>
++SOC_HEADER = include/asm-arm/arch-nomadik/soc_devices.h
++PDEV_HEADER = include/asm-arm/arch-nomadik/board_devices.h
+
-+#define DMA_NAME "DMA"
++$(TOPDIR)/.platform:
++ $(Q)echo "Generating $@"
++ $(Q)echo $(CONFIG_NOMADIK_PLATFORM) > $@
+
-+#ifndef DMA_DEBUG
-+#define DMA_DEBUG 0
-+#endif
++$(TOPDIR)/.soc:
++ $(Q)echo "Generating $@"
++ $(Q)echo $(CONFIG_NOMADIK_SOC) > $@
+
-+#define NMDK_DEBUG DMA_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX DMA_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++$(TOPDIR)/.target:
++ $(Q)echo "Generating $@"
++ $(Q)echo $(CONFIG_NOMADIK_TARGET) > $@
+
-+/* Macros used to identify standard dma structure elements for Nomadik implimentation*/
-+#define dmaconfig_pipeadr(x) ((x)->dma_base)
++$(TOPDIR)/$(PDEV_HEADER):
++ $(Q)echo "Generating SYMLINK $(PDEV_HEADER) -> $(PLATFORM_NAME)_devices.h"
++ $(Q)rm -rf $@
++ $(Q)ln -s $(PLATFORM_NAME)_devices.h $@
+
-+#define dmaconfig_defconfig(x) ((x)->buf.page)
-+#define dmaconfig_config(x) ((x)->buf.offset)
-+#define dmaconfig_usrconfig(x) ((x)->buf.dma_address)
-+#define dmaconfig_mode(x) ((x)->buf.length)
++$(TOPDIR)/$(SOC_HEADER):
++ $(Q)echo "Generating SYMLINK $(SOC_HEADER) -> $(SOC_NAME)_devices.h"
++ $(Q)rm -rf $@
++ $(Q)ln -s $(SOC_NAME)_devices.h $@
+
-+#define dmaconfig_srcadr(x) ((x)->cur_sg.dma_address)
-+#define dmaconfig_destadr(x) ((x)->cur_sg.length)
++# machprepare kjhsdk dfsdf
++machprepare: $(TOPDIR)/.platform $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/$(SOC_HEADER)
+
-+/*
-+ * Constants used for DMA channel priority processing
-+ */
-+#define QUEUE_ID 0x80
-+#define POLICY_CHECK_END 0xff
-+const u8 policy_mem2mem[10] ={15,14,13,12,
-+ QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
-+ POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_undefined[34] ={11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,
-+ QUEUE_ID+11,QUEUE_ID+10,QUEUE_ID+9,QUEUE_ID+8,
-+ QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
-+ QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
-+ QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
-+ POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_high[34] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
-+ QUEUE_ID+0,QUEUE_ID+1,QUEUE_ID+2,QUEUE_ID+3,
-+ QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
-+ QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
-+ QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
-+ POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_normal[34] ={4,5,6,7,8,9,10,11,3,2,1,0,12,13,14,15,
-+ QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
-+ QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
-+ QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
-+ QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
-+ POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_low[34] ={8,9,10,11,7,6,5,4,3,2,1,0,12,13,14,15,
-+ QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
-+ QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
-+ QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
-+ QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
-+ POLICY_CHECK_END, POLICY_CHECK_END};
++# machprepare kjhsdk j
++machclean:
++ $(Q)rm -rf *mod.o *.mod.c *.o *.ko
+
++machmrproper:
++ $(Q)rm -rf $(TOPDIR)/$(SOC_HEADER) $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/arch/arm/mach-nomadik/Kconfig $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/.platform
+
-+static char dmach_name[MAX_DMA_CHANNELS * MAX_DMA_CHNAME_SIZE];
-+static struct dma_soc_data *socdat;
-+static struct dmach_lli *p_lli_pipe[MAX_DMA_HWCHANNELS];
-+struct dmach_lli *lli_ptr_log = NULL;
-+struct dmach_lli *lli_ptr_phy = NULL;
-+#define nomadik_dma_lli_phy_to_logical(x) ((struct dmach_lli *)((u32)(x + (lli_ptr_log - lli_ptr_phy)) & ~0x01))
++#This will resolve any machin specific dependency for configuration
++#This will generate Kconfig file if not present
++machconfig:
++ifneq ($(wildcard $(TOPDIR)/arch/arm/mach-nomadik/Kconfig), $(TOPDIR)/arch/arm/mach-nomadik/Kconfig)
++ @echo "Generating $(TOPDIR)/arch/arm/mach-nomadik/Kconfig"
++ @./create_kconfig.pl $(TOPDIR)/arch/arm/mach-nomadik
++endif
+
-+#define nomadik_dmach_is_active_n_enabled(x) (x & 0x00020001)
-+#define nomadik_dma_is_pipe_busy(pipe) (p_lli_pipe[pipe])
-+#define nomadik_dma_mark_pipe_busy(pipe) (p_lli_pipe[pipe] = (void *)0xffffffff)
++# end of Auto board configuration/dependency resolution
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot
+@@ -0,0 +1,4 @@
++ zreladdr-y := 0x00008000
++params_phys-y := 0x00000100
++initrd_phys-y := 0x00800000
+
-+/**
-+ * nomadik_dma_channel_of_pipe - To get dma channel irq for provided pipe address
-+ * @pipeadr: pipe address w.r.to which channel irq needs for foundout
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/clock.c
+@@ -0,0 +1,127 @@
++/*
++ * linux/arch/arm/mach-nomadik/clock.c
+ *
-+ * finds the pipe number assoicated with channel
-+ * if any transfer is already scheduled on a pipe, returns the channel irq of scheduled DMA
-+ * if pipe is free, returns null
-+ */
-+static int nomadik_dma_channel_of_pipe(struct dmach_register *pipeadr)
-+{
-+ u32 pipe;
-+ struct dma_struct * dma;
-+
-+ pipe= (((u32)pipeadr & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
-+ if ((u32 *)pipeadr > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
-+ if (p_lli_pipe[pipe]) {
-+ if (p_lli_pipe[pipe]->mem2.dma) {
-+ dma = p_lli_pipe[pipe]->mem2.dma;
-+ return dma->dma_irq;
-+ } else return 0;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * nomadik_dma_allocate_llis - Allocates requested number of LLIs
-+ * @count: No of LLI buffers requested
++ * Copyright (C) 2004 ARM Limited.
++ * Written by Deep Blue Solutions Limited.
+ *
-+ * reserves the requested number of llis from internal lli poolf
-+ * link them with DMAble LLI addresses so that can be used directly by DMA h/w
-+ * return the point of first lli
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
+ */
-+static struct dmach_lli *nomadik_dma_allocate_llis(u32 count)
-+{
-+ struct dmach_lli *p_lli = lli_ptr_log;
-+ struct dmach_lli *p_lli_phy = lli_ptr_phy;
-+ struct dmach_lli *p_lli_phylast = (struct dmach_lli *)0x01;
-+ unsigned long flags;
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/errno.h>
++#include <linux/err.h>
++#include <linux/string.h>
++#include <linux/clk.h>
++#include <linux/mutex.h>
+
-+ nmdk_dbg_ftrace();
-+ if (!(p_lli) || !(count)) return (struct dmach_lli *)NULL;
-+ if (count > MAX_DMA_LLIS) return (struct dmach_lli *)NULL;
-+ flags = claim_dma_lock();
-+ do {
-+ if (p_lli == (lli_ptr_log + MAX_DMA_LLIS-2)) {
-+ nmdk_error("unable to find free lli.. rechecking...");
-+ p_lli = lli_ptr_log;
-+ p_lli_phy = lli_ptr_phy;
-+ }
-+ p_lli++; p_lli_phy++;
-+ if (!(p_lli->mem3.next)) {
-+ p_lli->mem3.next = p_lli_phylast;
-+ count--;
-+ p_lli_phylast = (struct dmach_lli *)((u32)p_lli_phy + 0x01);
-+ }
-+ } while (count);
-+ release_dma_lock(flags);
-+ return p_lli;
-+}
++#include <asm/semaphore.h>
++#include <asm/hardware/icst525.h>
++#include "clock.h"
+
-+/**
-+ * nomadik_dma_deallocate_llis - deallocates/frees the provided lli list
-+ * @p_lli: pointer to the first lli
-+ *
-+ * frees all llis in the provided lli list
-+ */
-+static void nomadik_dma_deallocate_llis(struct dmach_lli *p_lli)
++static LIST_HEAD(clocks);
++static DEFINE_MUTEX(clocks_mutex);
++
++struct clk *clk_get(struct device *dev, const char *id)
+{
-+ struct dmach_lli *p_lli_bkup;
++ struct clk *p, *clk = ERR_PTR(-ENOENT);
+
-+ nmdk_dbg_ftrace();
-+ while (p_lli) {
-+ if (!(p_lli)) break;
-+ if (!(p_lli->mem3.next)) break;
-+ if ((u32)p_lli->mem3.next == 0x01) {
-+ p_lli->mem3.next = (struct dmach_lli *)NULL;
++ mutex_lock(&clocks_mutex);
++ list_for_each_entry(p, &clocks, node) {
++ if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
++ clk = p;
+ break;
+ }
-+ p_lli_bkup = nomadik_dma_lli_phy_to_logical(p_lli->mem3.next);
-+ p_lli->mem3.next = (struct dmach_lli *)NULL;
-+ p_lli = p_lli_bkup;
+ }
++ mutex_unlock(&clocks_mutex);
++
++ return clk;
+}
+
-+/**
-+ * nomadik_dma_schedule_xfer_on_pipe - Schedules DMA transfer lli on a pipe
-+ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
-+ * @p_lli: pointer to the lli to be scheduled
-+ *
-+ * finds out the pipe no associated with a pipe
-+ * checkes whether pipe is free or busy
-+ * if free then
-+ * Configures the pipe with LLI data
-+ * clears any pending interrupt on a pipe
-+ * marks pipe as busy
-+ * Enables DMA to strat transfer
-+ * if pipe is busy then
-+ * queues the lli on the pipe
-+ */
-+static void nomadik_dma_schedule_xfer_on_pipe(volatile struct dmach_register *p_pipe, struct dmach_lli *p_lli)
++EXPORT_SYMBOL(clk_get);
++
++void clk_put(struct clk *clk)
+{
-+ u32 pipe, i;
-+ struct dmach_lli *p_lli_hw, *p_lli_curr;
-+ volatile struct dma_register *p_dma_reg;
++ module_put(clk->owner);
++}
+
-+ nmdk_dbg_ftrace();
-+ i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
-+ pipe = i*2;
-+ if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
-+
-+ p_lli->mem1.p_lli_qh = (struct dmach_lli *)NULL; /*Marked this lli as last in queue*/
-+ p_lli_curr = p_lli_pipe[pipe];
-+ mb();
-+ if ((p_lli_curr != (void*)0xffffffff) && (p_lli_curr != NULL) ) {
-+ while (p_lli_curr->mem1.p_lli_qh) {
-+ nmdk_dbg2("currlli(%p) next_lli (%p)", p_lli_curr, p_lli_curr->mem1.p_lli_qh);
-+ p_lli_curr = p_lli_curr->mem1.p_lli_qh; /*go thr lli headers to point last lli head */
-+ }
-+ p_lli_curr->mem1.p_lli_qh = p_lli;
-+ nmdk_dbg2("lli(%p) is queued on PIPE %d at %p", p_lli, pipe, p_lli_curr);
-+ } else {
-+ /* clear any pending interrupt on this pipe if any */
-+ p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
-+ p_dma_reg->tcicr |= 1UL<<i;
-+ p_dma_reg->eicr |= 1UL<<i;
-+ nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
++EXPORT_SYMBOL(clk_put);
+
-+ /* program pipe for a transfer*/
-+ p_lli_pipe[pipe] = p_lli;
-+ p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
-+ p_pipe->sadr = p_lli_hw->mem1.sadr;
-+ p_pipe->dadr = p_lli_hw->mem2.dadr;
-+ p_pipe->lli = p_lli_hw->mem3.next;
-+ p_pipe->cr = p_lli_hw->mem4.cr;
-+ nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
-+ (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
-+ mb();
-+ p_pipe->cfg = p_lli->mem4.cfg;
-+ }
++int clk_enable(struct clk *clk)
++{
++ return 0;
+}
+
-+/**
-+ * nomadik_dma_free_procesed_pipe - Frees processed LLI on a pipe
-+ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
-+ *
-+ * finds out the pipe no associated with a pipe
-+ * checkes whether pipe is free or busy, if free then just returns
-+ * frees the allocated llis for a pipe
-+ * checks whether any transfer is queued on a pipe
-+ * if the queue is not empty then
-+ * Configures queues lli as current lli
-+ * Configures the pipe with LLI data
-+ * clears any pending interrupt on a pipe
-+ * marks pipe as busy
-+ * Enables DMA to strat transfer
-+ * if the queue is empty then
-+ * marks the pipe as free if not reserved by requesting DMA Channel
-+ * otherwise marks the pipe as free
-+ */
-+static void nomadik_dma_free_procesed_pipe(volatile struct dmach_register *p_pipe)
++EXPORT_SYMBOL(clk_enable);
++
++void clk_disable(struct clk *clk)
+{
-+ u32 pipe;
-+ struct dmach_lli *p_lli;
-+ dma_t *dma;
-+ struct dmach_lli *p_lli_hw;
-+ volatile struct dma_register *p_dma_reg;
-+ u32 i;
++}
+
-+ nmdk_dbg_ftrace();
-+ i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
-+ pipe = i*2;
-+ if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
++EXPORT_SYMBOL(clk_disable);
+
-+ /* free lli of processed pipe*/
-+ if ((p_lli_pipe[pipe] != (void *)0xffffffff) && (p_lli_pipe[pipe] != NULL) ) {
-+ dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
-+ p_lli = p_lli_pipe[pipe]->mem1.p_lli_qh;
-+ nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
-+ mb();
-+ if (p_lli) {
-+ /* clear any pending interrupt on this pipe if any */
-+ p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
-+ /*p_dma_reg->tcicr |= 1UL<<i;*/
-+ p_dma_reg->eicr |= 1UL<<i;
-+ nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
-+
-+ /* program pipe for a transfer*/
-+ p_lli_pipe[pipe] = p_lli;
-+ p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
-+ p_pipe->sadr = p_lli_hw->mem1.sadr;
-+ p_pipe->dadr = p_lli_hw->mem2.dadr;
-+ p_pipe->lli = p_lli_hw->mem3.next;
-+ p_pipe->cr = p_lli_hw->mem4.cr;
-+ nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
-+ (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
-+ mb();
-+ p_pipe->cfg = p_lli->mem4.cfg;
++unsigned long clk_get_rate(struct clk *clk)
++{
++ return clk->rate;
++}
+
-+ nmdk_dbg2("Scheduling queued transfer on pipe %d (lli(%p))", pipe,
-+ p_lli_pipe[pipe]);
-+ } else {
-+ if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
-+ p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
-+ else {
-+ p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
-+ dmaconfig_pipeadr(dma) = (u32)0;
-+ }
-+ }
-+ }
++EXPORT_SYMBOL(clk_get_rate);
++
++long clk_round_rate(struct clk *clk, unsigned long rate)
++{
++ return 0;
+}
+
-+/* removes all allocated requests on the pipe */
-+/**
-+ * nomadik_dma_flush_pipe - Removes all scheduled and queued transfers on a pipe
-+ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
-+ *
-+ * finds out the pipe no associated with a pipe
-+ * stops current transfer
-+ * traverse through lli heads and flush all queued llis including scheduled one
-+ * marks the pipe as free
++EXPORT_SYMBOL(clk_round_rate);
++
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++ clk->rate = rate;
++ return 0;
++}
++
++EXPORT_SYMBOL(clk_set_rate);
++
++/*
++ * These are fixed clocks.
+ */
-+static void nomadik_dma_flush_pipe(volatile struct dmach_register *p_pipe)
++
++static struct clk uart_clk = {
++ .name = "UARTCLK",
++ .rate = 48000000,
++};
++
++static struct clk clcd_clk = {
++ .name = "CLCDCLK",
++ .rate = 48000000,
++};
++
++int clk_register(struct clk *clk)
+{
-+ u32 pipe;
-+ struct dmach_lli *p_lli_qh = (struct dmach_lli *)NULL;
-+ dma_t *dma;
++ mutex_lock(&clocks_mutex);
++ list_add(&clk->node, &clocks);
++ mutex_unlock(&clocks_mutex);
++ return 0;
++}
+
-+ nmdk_dbg_ftrace();
-+ pipe= (((u32)p_pipe & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
-+ if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
++EXPORT_SYMBOL(clk_register);
+
-+ if ((u32)p_lli_pipe[pipe] == 0xffffffff) goto nextt;
-+ while (p_lli_pipe[pipe] != 0) {
-+ dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
-+ p_lli_qh = p_lli_pipe[pipe]->mem1.p_lli_qh;
-+ nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
-+ p_lli_pipe[pipe] = p_lli_qh;
-+ nmdk_dbg2("Flushed lli (%p) for pipe %d", p_lli_pipe[pipe], pipe);
-+ };
-+ nextt:
-+// if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
-+// p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
-+// else
-+ p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
++void clk_unregister(struct clk *clk)
++{
++ mutex_lock(&clocks_mutex);
++ list_del(&clk->node);
++ mutex_unlock(&clocks_mutex);
+}
+
-+/**
-+ * nomadik_dma_check_update_userconfig - updates config as per user configs
-+ * @dma: DMA channel structure pointer
-+ *
-+ * checks the user configuration
-+ * if some use configuration is provided by clinet driver during
-+ * configuration then abstracts it and updates Channel configuration
-+ * data accordingly
-+ */
-+static void nomadik_dma_check_update_userconfig(dma_t *dma)
++EXPORT_SYMBOL(clk_unregister);
++
++static int __init clk_init(void)
+{
-+ nmdk_dbg_ftrace();
-+ if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_BSIZE_CONFIGURED) {
-+ dmaconfig_config(dma) &= ~(DMA_BSIZE_256);
-+ dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_BSIZE_256);
-+ }
-+ if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_BSIZE_CONFIGURED) {
-+ dmaconfig_config(dma) &= ~(DMA_BSIZE_256<<3);
-+ dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_BSIZE_256<<3);
-+ }
-+ if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_WIDTH_CONFIGURED) {
-+ dmaconfig_config(dma) &= ~(DMA_WIDTH_NA);
-+ dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_WIDTH_NA);
-+ }
-+ if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_WIDTH_CONFIGURED) {
-+ dmaconfig_config(dma) &= ~(DMA_WIDTH_NA<<3);
-+ dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_WIDTH_NA<<3);
-+ }
-+ nmdk_dbg("usrconfig =%08x, config = %08x", (u32)dmaconfig_usrconfig(dma), (u32)dmaconfig_config(dma));
++ clk_register(&uart_clk);
++ clk_register(&clcd_clk);
++ return 0;
+}
+
-+/**
-+ * nomadik_dma_usrdevconfig - updates user configuration as per type
-+ * @config: user configuration information
-+ * @type: src or destincation peripharal indicator (0= means src)
++arch_initcall(clk_init);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/clock.h
+@@ -0,0 +1,25 @@
++/*
++ * linux/arch/arm/mach-nomadik/clock.h
+ *
-+ * checks provided configuration and returns configuration converting
-+ * it for soruce or destination peripharal. this API is provided to
-+ * facilitate and mistake proffing the configuration by client driver
++ * Copyright (C) 2004 ARM Limited.
++ * Written by Deep Blue Solutions Limited.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
+ */
-+u32 __nomadik_dma_usrdevconfig(u32 config, int type)
-+{
-+ u32 val =0;
-+ if (type == 0) { /*src*/
-+ if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
-+ val |= DMA_SRC_BSIZE_CONFIGURED;
-+ val |= (config & DMA_BSIZE_256);
-+ }
-+ if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
-+ val |= DMA_SRC_WIDTH_CONFIGURED;
-+ val |= (config & DMA_WIDTH_NA);
-+ }
-+ } else { /*dest*/
-+ if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
-+ val |= DMA_DEST_BSIZE_CONFIGURED;
-+ val |= (config & DMA_BSIZE_256)<<3;
-+ }
-+ if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
-+ val |= DMA_DEST_WIDTH_CONFIGURED;
-+ val |= (config & DMA_WIDTH_NA)<<3;
-+ }
-+ }
-+ return (val);
-+}
-+EXPORT_SYMBOL(__nomadik_dma_usrdevconfig);
++struct module;
++struct icst525_params;
+
-+/**
-+ * nomadik_dmach_configure - configures DMA Channel processing default and user configuration
-+ * @srcdmadev: name of srouce DMAble device IP
-+ * @destdmadev: name of dest DMAble device IP
-+ * @dma: DMA channel data structure pointer
++struct clk {
++ struct list_head node;
++ unsigned long rate;
++ struct module *owner;
++ const char *name;
++ const struct icst525_params *params;
++ void *data;
++ void (*setvco)(struct clk *, struct icst525_vco vco);
++};
++
++int clk_register(struct clk *clk);
++void clk_unregister(struct clk *clk);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/cpu.c
+@@ -0,0 +1,293 @@
++/*
++ * linux/arch/arm/mach-nomadik/cpu.c
+ *
-+ * finds out the defult configuration for src and dest devices scanning the config_tbl
-+ * prepares DMA configuration from default config of src and dest dmadevices and user
-+ * configuration
-+ * return 0 on cusess, negative value on failure
++ * Copyright (C) STMicroelectronics
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * CPU freq driver
+ */
-+static int nomadik_dmach_configure(char *src_dmadev, char *dest_dmadev, dma_t *dma)
-+{
-+ int i;
-+ uint8 flag =0;
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/cpufreq.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/init.h>
+
-+ nmdk_dbg_ftrace();
-+ dmaconfig_config(dma) = 0;
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/mach-types.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/power.h>
+
-+ for (i=0; i < socdat->config_tbl_size; i++) {
-+ if (!(strcmp (src_dmadev, (socdat->config_tbl[i].id)))) {
-+ dmaconfig_config(dma) |= (u32) (socdat->config_tbl[i].config &
-+ (DMA_AHB_M1 | DMA_DEV_BOTH_DMACS_CANBE_USED | DMA_ADR_INC |
-+ DMA_WIDTH_NA | DMA_BSIZE_256 |
-+ DMA_REQUEST_LINE(31)));
-+ flag |=0x01;
-+ }
-+ if (!(strcmp(dest_dmadev,(socdat->config_tbl[i].id)))) {
-+ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config
-+ & DMA_DEV_BOTH_DMACS_CANBE_USED)<<2));
-+ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_AHB_M1)<<1));
-+ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_ADR_INC)<<1)); /*DI bit*/
-+ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_WIDTH_NA)<<3));
-+ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_BSIZE_256)<<3));
-+ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_REQUEST_LINE(31))<<5));
-+ flag |=0x02;
-+ }
-+ if ((flag & 0x03) == 0x03) {
-+ nomadik_dma_check_update_userconfig(dma);
-+ nmdk_dbg("conf(%08x), mode=%08x", dmaconfig_config(dma), dmaconfig_mode(dma));
-+ return(0);
-+ }
-+ }
-+ nmdk_error("unable to configure dmachanel");
-+ return(-1);
-+}
++#include <asm/arch/debug.h>
+
-+/**
-+ * nomadik_dma_find_dmahwpipe - Finds and returns free and compatible DMA pipe
-+ * @dma: DMA channel data structure pointer
-+ *
-+ * searches a free pipe as per channel priority policy manager
-+ * (refer ./Documentation//arm/STM-Nomadik/dma_user_guide.txt)
-+ * checks the configuration for the pipe suitability for transfer
-+ * selects the pipe and mark it as busy
-+ * returns pipe address if selected
-+ * returns NULL in case of unavailability of pipe
++#define CPUFREQ_NAME "CPUFREQ"
++
++#ifndef CPUFREQ_DEBUG
++#define CPUFREQ_DEBUG 0
++#endif
++
++#define NMDK_DEBUG CPUFREQ_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX CPUFREQ_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++
++#define PLL1_CRYSTAL_FREQ_KHZ (192 * 100)
++#define CALC_FREQ(pll1_nmul, pll1_pdiv) (PLL1_CRYSTAL_FREQ_KHZ * (pll1_nmul + 2)) / (1 << pll1_pdiv);
++
++static struct cpufreq_driver nomadik_driver;
++static unsigned int nomadik_get(unsigned int cpu);
++
++extern unsigned int nomadik_freq_to_idx(unsigned int freq);
++extern unsigned int nomadik_idx_to_freq(unsigned int idx);
++extern u32 nomadik_setsys_freq(u32 freq_idx);
++
++/*
++ * Validate the speed policy.
+ */
-+static struct dmach_register *nomadik_dma_find_dmahwpipe(dma_t *dma)
++static int nomadik_verify_policy(struct cpufreq_policy *policy)
+{
-+ int i;
-+ u8 *p_pipe;
-+ volatile struct dmach_register *p_dmach_reg;
-+ volatile struct dma_register *p_dma_reg;
-+ unsigned long flags;
+
+ nmdk_dbg_ftrace();
++ cpufreq_verify_within_limits(policy,
++ policy->cpuinfo.min_freq,
++ policy->cpuinfo.max_freq);
+
-+ flags = claim_dma_lock();
-+ /* channel priority setup */
-+ if ( MEM_TO_MEM == (u32)dmaconfig_mode(dma)) {
-+ p_pipe = (void *)policy_mem2mem;
-+ }
-+ else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_HIGH) {
-+ p_pipe = (void *)policy_high;
-+ }
-+ else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_NORMAL) {
-+ p_pipe = (void *)policy_normal;
-+ }
-+ else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_LOW) {
-+ p_pipe = (void *)policy_low;
-+ }
-+ else { /* DMA_EXCH_PRIORITY_UNDEFINED) */
-+ p_pipe = (void *)policy_undefined;
-+ }
-+ do {
-+ i = *p_pipe & ~QUEUE_ID;
-+ /** Advanced Pipe selection strategy, under development */
-+ /* skip if pipe is busy and not requested on queued pipe */
-+ if (nomadik_dma_is_pipe_busy(i) && (!(*p_pipe & QUEUE_ID))) continue;
-+ /* skip if pipe is busy with infinite dma xfer */
-+ if (nomadik_dma_is_pipe_busy(i) &&
-+ ((dmaconfig_config((dma_t *)p_lli_pipe[i]->mem2.dma)) & DMA_INFINITE_XFER)) continue;
-+ if (i & 0x01) {
-+ if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)))
-+ != (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)) ) continue;
-+ p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA1].chip_data;
-+ } else {
-+ if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)))
-+ != (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)) ) continue;
-+ p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA0].chip_data;
-+ }
-+ p_dmach_reg = (struct dmach_register *)&p_dma_reg->dmach[i/2];
-+ nomadik_dma_mark_pipe_busy(*p_pipe & ~QUEUE_ID);
-+ nmdk_dbg("DMAHW PIPE%d assigned for Dma Channel %d",i, DMACH_FOR_IRQNO(dma->dma_irq));
-+ release_dma_lock(flags);
-+ return (void *)p_dmach_reg;
-+ } while ((*(++p_pipe)) != POLICY_CHECK_END);
-+ release_dma_lock(flags);
-+ nmdk_error("All HW DMA Chanels busy...");
-+ return NULL;
++ policy->min = NOMADIK_CPUFREQ_MIN;
++ policy->max = NOMADIK_CPUFREQ_MAX;
++
++ cpufreq_verify_within_limits(policy,
++ policy->cpuinfo.min_freq,
++ policy->cpuinfo.max_freq);
++
++ return 0;
+}
+
-+/**
-+ * nomadik_dma_req - low level method for request_dma API
-+ * @channel: DMA channel number
-+ * @dma: DMA channel data structure pointer
-+ *
-+ * Check for configuration is passed by client
-+ * prepares basic channel configuration from dma info provided by client
-+ * generate dmach id string from src and dest dmadevtypes
-+ * find and reserved a pipe in case of reserved mode requested by client
-+ * returns NULL in case of sucess, negative value in case for failure
-+ */
-+static int nomadik_dma_req(dmach_t channel, dma_t *dma)
++static int nomadik_set_target(struct cpufreq_policy *policy,
++ unsigned int target_freq, unsigned int relation)
+{
-+ struct nmdk_dma_info *dma_info =
-+ (struct nmdk_dma_info *)dma->device_id;
-+ int error;
++ cpumask_t cpus_allowed;
++ int cpu = policy->cpu;
++ struct cpufreq_freqs freqs;
++ unsigned int freq_idx;
++ unsigned int new_voltage, cur_voltage;
++ unsigned char vcore_data;
++ int result;
+
-+ nmdk_dbg_ftrace();
++ nmdk_dbg2("%s called with target_freq = %d relation = %d\n",
++ (__FUNCTION__), target_freq, relation);
++ /*
++ * Save this threads cpus_allowed mask.
++ */
++ cpus_allowed = current->cpus_allowed;
+
-+ if (! dma->device_id) {
-+ nmdk_error("nmdk_dma_info structptr not passed");
-+ return (-DMA_CONFIG_INFO_NOT_PASSED);
++ /*
++ * Bind to the specified CPU. When this call returns,
++ * we should be running on the right CPU.
++ */
++ set_cpus_allowed(current, cpumask_of_cpu(cpu));
++ BUG_ON(cpu != smp_processor_id());
++
++ freqs.old = nomadik_get(policy->cpu);
++
++ freq_idx = nomadik_freq_to_idx(target_freq);
++
++ switch (relation) {
++ case CPUFREQ_RELATION_L:
++ if (nomadik_idx_to_freq(freq_idx) > policy->max)
++ freq_idx--;
++ break;
++ case CPUFREQ_RELATION_H:
++ if ((nomadik_idx_to_freq(freq_idx) > target_freq) &&
++ (nomadik_idx_to_freq(freq_idx - 1) >= policy->min))
++ freq_idx--;
++ break;
+ }
+
-+ dmaconfig_mode(dma) = (u32)dma_info->mode;
-+ dmaconfig_usrconfig(dma) = (u32)dma_info->config;
++ freqs.new = nomadik_idx_to_freq(freq_idx);
++ freqs.cpu = policy->cpu;
+
-+ /* Prepare dmach configuration form dma_info*/
-+ switch((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
-+ case MEM_TO_MEM:
-+ dma_info->srcdevtype = "mem";
-+ dma_info->destdevtype = "mem";
-+ break;
-+ case FLOW_CNTRL_PERIPH(MEM_TO_PERIPH):
-+ case MEM_TO_PERIPH:
-+ dma_info->srcdevtype = "mem";
-+ break;
-+ case FLOW_CNTRL_PERIPH(PERIPH_TO_MEM):
-+ case PERIPH_TO_MEM:
-+ dma_info->destdevtype = "mem";
-+ break;
-+ case FLOW_CNTRL_SRC_PERIPH(PERIPH_TO_PERIPH):
-+ case FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH):
-+ case PERIPH_TO_PERIPH:
-+ break;
-+ default:
-+ nmdk_error("Invalid DMA mode");
-+ error =-1;
-+ goto err_exit;
++ nmdk_dbg2(" freqs.new = %d\n", freqs.new);
++ if (freqs.old == freqs.new) {
++ set_cpus_allowed(current, cpus_allowed);
++ return 0;
+ }
-+
-+ if (! dma_info->srcdevtype) {
-+ nmdk_error("srcdevtype not specified");
-+ error =-DMA_SRC_DEVICE_NOT_CONFIGURED;
-+ goto err_exit;
++
++#if 0
++ if ( freq_idx == 0)
++ {
++ nomadik_normal_to_slow = 1;
++ nomadik_slow_to_normal = 0;
+ }
-+ if (! dma_info->destdevtype) {
-+ nmdk_error("destdevtype not specified");
-+ error =-DMA_DEST_DEVICE_NOT_CONFIGURED;
-+ goto err_exit;
++ if (freqs.old == 19200 )
++ {
++ nomadik_slow_to_normal = 1;
++ nomadik_normal_to_slow = 0;
++
+ }
-+ error = nomadik_dmach_configure(dma_info->srcdevtype, dma_info->destdevtype, dma);
-+ if (error) goto err_exit;
-+
-+ /* generate dmach id string from src and dest dmadevtypes */
-+ sprintf(dmach_name + (channel * MAX_DMA_CHNAME_SIZE ),
-+ "dmaclbk-%s->%s", dma_info->srcdevtype, dma_info->destdevtype);
-+ dma->device_id = dmach_name + (channel * MAX_DMA_CHNAME_SIZE) + 8;
++#endif
+
-+ if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) {
-+ dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
-+ if ((u32)dmaconfig_pipeadr(dma)) {
-+ nmdk_dbg("pipe (%p) reserved for channel %d",
-+ (void *)dmaconfig_pipeadr(dma), channel);
-+ } else {
-+ nmdk_error("could not reserve dmach hw pipe");
-+ error =-1;
-+ goto err_exit;
-+ }
-+ } else dmaconfig_pipeadr(dma) = (u32)NULL;
-+ dma->state = NMDK_DMA_CONFIGURED;
-+ return(0);
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
-+ err_exit:
-+ return(error);
-+}
++ new_voltage = nomadik_freq_to_voltage(freqs.new);
++ cur_voltage = g_nomadik_voltage;
++ nmdk_dbg2(" new voltage = %d\n", new_voltage);
++ nmdk_dbg2(" old voltage = %d\n", cur_voltage);
+
-+/**
-+ * nomadik_dma_en - low level method for enable_dma API
-+ * @channel: DMA channel number
-+ * @dma: DMA channel data structure pointer
-+ *
-+ * Checks for channel configured properly
-+ * allocates llis for transfer
-+ * programm llis for transfer data
-+ * checks if the pipe is already available with channel
-+ * if not the find and allocates a free pipe for a transfer
-+ * program dmach irqname if not set by client
-+ * schedules a transfer on a pipe
-+ */
-+static void nomadik_dma_en(dmach_t channel, dma_t *dma)
-+{
-+ struct dmach_lli *p_lli_start = (struct dmach_lli *)NULL;
-+ struct dmach_lli *p_lli_curr;
-+ struct dmach_lli *p_lli_next;
++ if (new_voltage > cur_voltage) {
+
-+ unsigned long flags;
-+ u32 dmacnt, dmacnt_chkval, tmpcnt;
++ vcore_data = new_voltage;
+
-+ nmdk_dbg_ftrace();
++ result =
++ nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
++ 0x1E, 1);
++ if (unlikely(result)) {
++ nmdk_error("i2c write error with ret = %d\n", result);
++ goto err1;
+
-+/* if (dma->invalid) {
-+ if (dma->mode) {
-+ if (((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH) ==
-+ (dma->mode & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
-+ dmaconfig_mode(dma) = (u32)dma->mode;
-+ }
-+ }
-+ } else {
-+ exit_invl_parms:
-+ nmdk_error("enable request without parameters");
-+ goto exit_en
-+ }
-+ if (dma->addr) dmaconfig_srcadr(x) = dma->addr;
-+ if (dma->speed) dmaconfig_destadr(x) = (u32)dma->speed;
-+*/
++ } else
++ nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
+
-+ if (!(dma->sg)) {
-+ if (!(dma->addr)) {
-+ nmdk_error("srcadr not set");
-+ goto exit_en;
-+ }
-+ if (!(dma->speed)) {
-+ nmdk_error("destadr not set");
-+ goto exit_en;
-+ }
-+ }
++#ifdef CPUFREQ_DEBUG
++ vcore_data = 0;
+
-+ /*set transfer size = count/src_width */
-+ dmacnt = dma->count/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
-+ nmdk_dbg("total count = %d, dma count =%d",(u32)dma->count, dmacnt);
-+ tmpcnt = 0;
-+ dmacnt_chkval = 0x0ff0;
++ result =
++ nomadik_i2c_read_register(I2C_TOUAREG_CLIENT, &vcore_data,
++ 0x1E, 1);
++ if (unlikely(result)) {
++ nmdk_error("i2c read error with ret = %d\n", result);
++ goto err1;
+
-+ if (dma->sg) {
-+ /*Scatter gather list implimentation */
-+ if (dma->sgcount == 0) {
-+ nmdk_error("Empty scatter gather list");
-+ goto exit_en;
-+ }
-+ if ((((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_MEM ) ||
-+ (((u32)dmaconfig_mode(dma) & 0x03) == PERIPH_TO_PERIPH )) {
-+ nmdk_error("Unsupported mode for scatter gather");
-+ goto exit_en;
-+ }
-+ p_lli_start = nomadik_dma_allocate_llis(dma->sgcount +1);
-+ p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
-+#ifdef SCATERGATHER_MMC_DEBUG
-+ if (dma->sgcount > 1) {
-+ dmaconfig_config(dma) |= 0x0f0007fe;
-+ nmdk_dbg("sc_count=%d , config=%08x", dma->sgcount, dmaconfig_config(dma));
-+ if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
-+ printk("===%p", dma_alloc_coherent( NULL , 4096, &dma->speed, GFP_DMA | GFP_KERNEL ));
++ } else
++ nmdk_dbg2("i2c read vcore_data = 0x%x\n", vcore_data);
+
-+ } else {
-+ printk("==%p",dma_alloc_coherent( NULL , 4096, &dma->addr, GFP_DMA | GFP_KERNEL ));
-+ }
-+ dmaconfig_mode(dma) = 0;
++ if ( vcore_data != new_voltage )
++ {
++ printk("i2c had not written correctly\n");
++ goto err1;
+ }
+#endif
-+ tmpcnt = dma->count;
-+ while (dma->sgcount) {
-+ nmdk_dbg("tmpcnt %d, sg_len %d", tmpcnt, dma->sg->length);
-+ p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
-+ if (!(dma->sg->dma_address)) {
-+ nmdk_error("sg list not dma mapped");
-+ goto exit_en;
-+ }
-+ if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
-+ p_lli_curr->mem1.sadr = dma->sg->dma_address;
-+ if (!(dma->speed)) {
-+ nmdk_error("destadr not set");
-+ goto exit_en;
-+ }
-+ p_lli_curr->mem2.dadr = (dma_addr_t)dma->speed;
-+ } else {
-+ if (!(dma->addr)) {
-+ nmdk_error("srcadr not set");
-+ goto exit_en;
-+ }
-+ p_lli_curr->mem1.sadr = (dma_addr_t)dma->addr;
-+ p_lli_curr->mem2.dadr = dma->sg->dma_address;
-+ }
-+ if (tmpcnt > dma->sg->length) {
-+ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+ (dma->sg->length/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
-+ } else {
-+ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+ (tmpcnt/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
-+ }
-+ tmpcnt -= dma->sg->length;
-+ dma->sgcount--; dma->sg++;
-+ if (dma->sgcount == 0) p_lli_curr->mem4.cr |= (1<<31);
-+ p_lli_curr = p_lli_next;
-+ }
-+ } else if ((u32)dmaconfig_mode(dma) & DMA_DOUBLE_BUFFERED ) {
-+ p_lli_start = nomadik_dma_allocate_llis(3);
-+ p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
-+ p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
++ g_nomadik_voltage = new_voltage;
++ }
+
-+ dmacnt /= 2;
-+ dmacnt_chkval = dmacnt;
-+ /*fill next lli structure */
-+ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | dmacnt_chkval);
-+ p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
-+ p_lli_curr->mem2.dadr = dma->speed;
-+ p_lli_next->mem4.cr = p_lli_curr->mem4.cr;
-+ p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
-+ p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
-+ if (p_lli_next->mem4.cr & DMA_ADR_INC) p_lli_next->mem1.sadr += dma->count/2;
-+ if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1)) p_lli_next->mem2.dadr += dma->count/2;
++ nomadik_setsys_freq(freq_idx);
+
-+ if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
-+ p_lli_next->mem3.next = p_lli_start->mem3.p_lli_hw;
-+ } else {
-+ p_lli_next->mem4.cr |= (1<<31);
-+ }
-+ } /*mode & DMA_DOUBLE_BUFFERED*/
-+ else {
-+ tmpcnt = dmacnt/dmacnt_chkval;
-+ p_lli_start = nomadik_dma_allocate_llis(tmpcnt + 2);
-+ p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
-+ p_lli_next = p_lli_curr;
++ if (new_voltage < cur_voltage) {
++
++ vcore_data = new_voltage;
++ result =
++ nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
++ 0x1E, 1);
++ /**
++ * Here even if we are not able to set lower voltage. Still system can
++ * work with previous voltage
++ */
++
++ if (unlikely(result)) {
++ nmdk_error("i2c write error with ret = %d\n", result);
++ goto err1;
++
++ } else
++ nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
++ g_nomadik_voltage = new_voltage;
+
-+ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+ ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
-+ dmacnt -= dmacnt_chkval;
-+ p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
-+ p_lli_curr->mem2.dadr = dma->speed;
-+ while(tmpcnt) {
-+ p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
-+ /*fill next lli structure */
-+ p_lli_next->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+ ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
-+ p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
-+ p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
-+ if (p_lli_next->mem4.cr & DMA_ADR_INC)
-+ p_lli_next->mem1.sadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
-+ if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1))
-+ p_lli_next->mem2.dadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
-+
-+ p_lli_curr = p_lli_next;
-+ dmacnt -= dmacnt_chkval;
-+ tmpcnt--;
-+ }
-+ p_lli_curr->mem4.cr |= (1<<31);
-+ if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
-+ p_lli_curr->mem3.next = p_lli_start->mem3.p_lli_hw;
-+ } else {
-+ p_lli_curr->mem4.cr |= (1<<31);
-+ }
+ }
-+ nmdk_dbg("lli_start(%p)", p_lli_start);
-+ p_lli_start->mem2.dma = (void *)dma; /*dma associated with this lii*/
-+ p_lli_start->mem4.cfg = (((u32)dmaconfig_config(dma) & 0x000007fe) | /* set src/dest dma periph request line numbers */
-+ ((u32)dmaconfig_mode(dma)<<11 & (7<<11)) | /* set flow control and xter type*/
-+ (0x0000c001)); /*enable interrupts and start xfer*/
+
-+ /* if channel is reserved use predefined hwpipe else find free
-+ * h/w pipe to schedule dma
-+ * if h/w pipe is not available the que the request
++ err1:
++
++ /*
++ * Restore the CPUs allowed mask.
+ */
-+ if (!((u32)dmaconfig_pipeadr(dma))) {
-+ dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
-+ if (dmaconfig_pipeadr(dma)) {
-+ nmdk_dbg("channel %d allocated pipe p_dmach_reg(%p) ",channel, (void *)dmaconfig_pipeadr(dma));
-+ } else {
-+ nmdk_error("enable requested aborted...No pipe available...");
-+ goto exit_en;
-+ }
-+ }
-+ /* program dmach irqname if not set by client */
-+ if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
-+ if (!(socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name))
-+ socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name =
-+ (dmach_name + (channel * MAX_DMA_CHNAME_SIZE));
++ set_cpus_allowed(current, cpus_allowed);
+
-+ mb();
-+ flags = claim_dma_lock();
-+ nomadik_dma_schedule_xfer_on_pipe((void *)dmaconfig_pipeadr(dma), p_lli_start);
-+ release_dma_lock(flags);
-+ dma->state = NMDK_DMA_ENABLED;
-+ if ((u32)dmaconfig_mode(dma) & DMA_QUEUE_ENABLED) dma->active = 0;
-+ return;
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++#if CPUFREQ_DEBUG
++ {
++ int j;
++ for(j=0; j <= 0x124; j+=4)
++ printk("sdmc[%x] = %x\n", j, readl(0xf0110000 + j ));
++ }
++#endif
+
-+exit_en:
-+ if (p_lli_start) nomadik_dma_deallocate_llis(p_lli_start);
-+ return;
++ return 0;
+}
+
-+/**
-+ * nomadik_dma_dis - low level method for disable_dma API
-+ * @channel: DMA channel number
-+ * @dma: DMA channel data structure pointer
-+ *
-+ * disables a transfer on a pipe if associated with a requested channel
-+ */
-+static void nomadik_dma_dis(dmach_t channel, dma_t *dma)
++#define SRC_PLL_FREQ_OFFSET 0x14
++static unsigned int nomadik_get(unsigned int cpu)
+{
-+ struct dmach_register *p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
-+ unsigned long flags;
++ cpumask_t cpus_allowed;
++ unsigned int current_freq;
++ unsigned char __iomem *src_base;
++ unsigned long pll_reg;
++ unsigned int pll1_nmul, pll1_pdiv;
+
+ nmdk_dbg_ftrace();
++ cpus_allowed = current->cpus_allowed;
+
-+ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
-+ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+ flags = claim_dma_lock();
-+ nmdk_dbg("Channel %d disabled on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+ p_dmach_reg->cfg &= ~0x0000c001;
-+ release_dma_lock(flags);
-+ dma->state = NMDK_DMA_DISABLED;
++ set_cpus_allowed(current, cpumask_of_cpu(cpu));
++ BUG_ON(cpu != smp_processor_id());
++ src_base = (unsigned char *)IO_ADDRESS(NOMADIK_SRC_BASE);
++ if ( ( readl(src_base) & 0x78 ) == 0x20 )
++ {
++ pll_reg = readl(src_base + SRC_PLL_FREQ_OFFSET);
++ pll1_pdiv = pll_reg & 0x7;
++ pll1_nmul = (pll_reg >> 8) & 0x3f;
++ current_freq = CALC_FREQ(pll1_nmul, pll1_pdiv);
++ }
++ else
++ current_freq = NOMADIK_CPUFREQ_MIN;
++
++ set_cpus_allowed(current, cpus_allowed);
++ nmdk_dbg2("Current_freq = %d\n", current_freq);
++ nmdk_dbg2("pll1_nmul = 0x%x pll1_pdiv = 0x%x\n", pll1_nmul, pll1_pdiv);
++
++ g_nomadik_voltage = nomadik_freq_to_voltage(current_freq);
++ nmdk_dbg2("g_nomadik_voltage = %x\n", g_nomadik_voltage);
++ return current_freq;
+}
+
-+static void nomadik_dma_fr(dmach_t channel, dma_t *dma)
++static int nomadik_cpufreq_init(struct cpufreq_policy *policy)
+{
-+ nmdk_dbg_ftrace();
-+ nomadik_dma_dis(channel, dma);
-+ if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
-+ free_irq(IRQNO_FOR_DMACH(channel), socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->dev_id);
-+ if (dmaconfig_pipeadr(dma)) nomadik_dma_flush_pipe((void *)dmaconfig_pipeadr(dma));
++
++ /* set default policy and cpuinfo */
++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
++ policy->cpuinfo.max_freq = NOMADIK_CPUFREQ_MAX;
++ policy->cpuinfo.min_freq = NOMADIK_CPUFREQ_MIN;
++ policy->cpuinfo.transition_latency = NOMADIK_CPUFREQ_TRANS_LATENCY;
++ policy->cur = policy->min = policy->max = nomadik_get(policy->cpu);
++ nmdk_dbg2("max cpu freq = %d min cpu freq = %d\n", NOMADIK_CPUFREQ_MAX,
++ NOMADIK_CPUFREQ_MIN);
++
++ return 0;
+}
+
-+/* find the available dma chanel and requests the same */
-+/**
-+ * request_available_dma - Wrapper over request_dma API
-+ * @dmach_config_info: DMA channel number
-+ * @dma: DMA channel data structure pointer
-+ *
-+ * Wrapper over request_dma API for free and available DMA channel search
-+ * returns DMA Channel number , negative error value in case of failure
-+ */
-+int request_available_dma(struct nmdk_dma_info * dmach_config_info)
-+{
-+ dmach_t channel;
-+ int error;
++static struct cpufreq_driver nomadik_driver = {
++ .verify = nomadik_verify_policy,
++ .target = nomadik_set_target,
++ .get = nomadik_get,
++ .init = nomadik_cpufreq_init,
++ .name = "nomadik-cpufreq",
++};
+
-+ /*removed locks as detected by spinlock debugging on*/
-+ for (channel = 0; channel < (MAX_DMA_CHANNELS - 1); channel++) {
-+ error = request_dma(channel, (char *)dmach_config_info);
-+ if (-EBUSY == error) continue;
-+ if (error < 0) {
-+ nmdk_error("Request DMA error");
-+ return error;
-+ } else {
-+ nmdk_dbg("Dma Chanel %d is available and allocated", channel);
-+ return channel;
-+ }
-+ }
-+ nmdk_error("All DMA Channels occupied....");
-+ return -DMA_ALLCHANELS_OCCUPIED;
++static int __init nomadik_cpu_init(void)
++{
++ return cpufreq_register_driver(&nomadik_driver);
+}
-+EXPORT_SYMBOL(request_available_dma);
+
-+/**
-+ * suspend_dma - Pauses DMA transfer for this channel
-+ * @channel: DMA channel number
-+ *
-+ * This API will pause current dma if it is ongoing
-+ * also this API is used to pause all active on going DMA channels involved
-+ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
-+ */
-+void suspend_dma(dmach_t channel)
++static void __exit nomadik_cpu_exit(void)
+{
-+ dma_t *dma;
-+ volatile struct dmach_register *p_dmach_reg;
-+ unsigned long flags;
++ cpufreq_unregister_driver(&nomadik_driver);
++}
+
-+ nmdk_dbg_ftrace();
-+ if (!(socdat->dma_chan)) goto inactive_dma;
-+ dma = socdat->dma_chan;
-+ if (DMA_ALL_MEM_CHANNELS == channel) {
-+ for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
-+ if (!dma->lock) continue;
-+ if (NMDK_DMA_SUSPENDED == dma->state) continue;
-+ if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
-+ == PERIPH_TO_PERIPH) continue;
-+ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++MODULE_AUTHOR("Manish Rathi");
++MODULE_DESCRIPTION("cpufreq driver for ARM Nomadik CPUs");
++MODULE_LICENSE("GPL");
+
-+ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
-+ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+ flags = claim_dma_lock();
-+ nmdk_dbg("Channel %d Suspended on pipe %p", channel, (void *)dmaconfig_pipeadr(dma));
-+ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+ p_dmach_reg->cfg |= NMDK_DMACH_HALT;
-+ }
-+ release_dma_lock(flags);
-+ dma->state = NMDK_DMA_SUSPENDED;
++module_init(nomadik_cpu_init);
++module_exit(nomadik_cpu_exit);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl
+@@ -0,0 +1,55 @@
++#! /usr/bin/perl
++#
++# gen_nomadik_kconfig.pl: Generates Kconfig in arch/arm/mach-nomadik/ considering all board specific Kconfig files.
+
-+ dma++;
-+ }
-+ return;
-+ }
-+ if (!(socdat->dma_chan)) goto inactive_dma;
-+ dma += channel;
-+ if (!dma->lock)
-+ goto free_dma;
++$VAR=@ARGV;
++if (@ARGV != 1)
++{
++ print "Usage: ./create_kconfig.pl <filepath>\n";
++ print "example: ./create_kconfig.pl arch/arm/mach-nomadik\n";
++ exit(1);
++}
+
-+ if (NMDK_DMA_SUSPENDED == dma->state) return;
-+ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++$KPATH=@ARGV[0];
+
-+ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
-+ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+ flags = claim_dma_lock();
-+ nmdk_dbg("Channel %d Suspended on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+ p_dmach_reg->cfg |= NMDK_DMACH_HALT;
-+ }
-+ release_dma_lock(flags);
-+ dma->state = NMDK_DMA_SUSPENDED;
-+ return;
++@temp=split(/mach-/, $KPATH);
++@temp1=split(/\//, @temp[1]);
++$mach=@temp1[0];
++$machuc=uc($mach);
+
-+free_dma:
-+ printk(KERN_ERR "dma%d: trying to suspend free DMA\n", channel);
-+ BUG();
-+ return;
-+inactive_dma:
-+ printk(KERN_ERR "dma driver not active\n");
-+ BUG();
++if ( -e "$KPATH/Kconfig" ) {
++ exit(0);
+}
-+EXPORT_SYMBOL(suspend_dma);
+
++open (KCONFIG, "> $KPATH/Kconfig") || die "Can't open file: $!";
++$Kconfig_data="# Automatically generated Kconfig: don't edit\n# To add new board support create $KPATH/<board>_Kconfig file\n\nif ARCH_$machuc\n\nchoice\n\nprompt \"$mach target board\"\n\n";
++print KCONFIG $Kconfig_data;
+
-+/**
-+ * nomadik_dma_residue - low level method for get_dma_residue API
-+ * @channel: DMA channel number
-+ * @dma: DMA channel data structure pointer
-+ *
-+ * Pause the channel, read the control register, resume the channel
-+ * May not be an accurate value
-+ * returns bytes remaining on a transfer
-+ */
-+static int nomadik_dma_residue(dmach_t channel, dma_t *dma)
-+{
-+ volatile unsigned int r = 0;
-+ volatile struct dmach_register *p_dmach_reg =
-+ (struct dmach_register *)dmaconfig_pipeadr(dma);
++@filenames =qx(ls $KPATH/*_Kconfig);
++foreach $filename(@filenames)
++ {
++ @temp=split(/mach-$mach\//, $filename);
++ @temp1=split(/_Kconfig/, @temp[1]);
++ $filename=@temp1[0];
++ chomp($filename);
++ $filenameuc=uc($filename);
++ $usc="_";
++ print KCONFIG "config $machuc$usc$filenameuc\n\tbool \"$filename\"\n\thelp\n\t\tSupprots $filename target board for $mach platform\n\n";
++ };
+
-+ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return -1;
-+ suspend_dma(channel);
-+ mb();
++print KCONFIG "endchoice\n\n";
+
-+ /*get transfer bytes = src_width * transfer_size */
-+ r = p_dmach_reg->cr & 0x0fff;
-+ r *= ((p_dmach_reg->cr & 0x000c0000)>>17);
-+ mb();
-+ resume_dma(channel);
++@filenames =qx(ls $KPATH/*_Kconfig);
++foreach $filename(@filenames)
++ {
++ chomp($filename);
++ print KCONFIG "source \"$filename\"\n\n";
++ };
+
-+ return r;
++if ( -e "$KPATH/Kconfig-$mach" ) {
++ print KCONFIG "source \"$KPATH/Kconfig-$mach\"\n";
+}
+
-+/**
-+ * resume_dma - Resume already suspended DMA transfer for this channel
-+ * @channel: DMA channel number
++print KCONFIG "endif\n\n";
++close KCONFIG;
++
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S
+@@ -0,0 +1,655 @@
++/*
++ * arch/arm/mach-nomadik/deep_sleep.S
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
-+ * This API will resume current dma if it is suspended previously
-+ * also this API is used to resume all active and paused DMA channels involved
-+ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
+ */
-+void resume_dma(dmach_t channel)
-+{
-+ dma_t *dma;
-+ volatile struct dmach_register *p_dmach_reg;
-+ unsigned long flags;
+
-+ nmdk_dbg_ftrace();
-+ if (!(socdat->dma_chan)) goto inactive_dma;
-+ dma = socdat->dma_chan;
-+ if (DMA_ALL_MEM_CHANNELS == channel) {
-+ for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
-+ if (!dma->lock) continue;
-+ if (NMDK_DMA_SUSPENDED != dma->state) continue;
-+ if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
-+ == PERIPH_TO_PERIPH) continue;
-+ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++#include <asm/arch/hardware.h>
++#include <asm/arch/entry-macro.S>
+
-+ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
-+ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+ flags = claim_dma_lock();
-+ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+ p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
-+ }
-+ nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+ release_dma_lock(flags);
-+ dma->state = NMDK_DMA_RESUMED;
++.global nomadik_deep_sleep
++.extern L2dummyPointer
+
-+ }
-+ return;
-+ }
-+ dma += channel;
-+ if (!dma->lock)
-+ goto free_dma;
++nomadik_deep_sleep:
++ /*Store all the general purpose registers along with the link register*/
++ stmfd sp!,{r0-r12,lr}
+
-+ if (NMDK_DMA_SUSPENDED != dma->state) return;
-+ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++ /* save the first parameter passed to function nomadik_deep_sleep to r12*/
++ mov r12,r0
+
-+ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
-+ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+ flags = claim_dma_lock();
-+ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+ p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
-+ }
-+ nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+ release_dma_lock(flags);
-+ dma->state = NMDK_DMA_RESUMED;
-+ return;
++ /* save the second parameter passed to function nomadik_deep_sleep to the variable addr - mpmc_base*/
++ ldr r11, =mpmc_base
++ str r1,[r11]
+
-+free_dma:
-+ printk(KERN_ERR "dma%d: trying to resume free DMA\n", channel);
-+ BUG();
-+ return;
-+inactive_dma:
-+ printk(KERN_ERR "dma driver not active\n");
-+ BUG();
-+}
-+EXPORT_SYMBOL(resume_dma);
++ /* save the third parameter passed to function nomadik_deep_sleep to the variable addr - backup_ram_base */
++ ldr r11, =backup_ram_base
++ str r2,[r11]
+
-+/**
-+ * nomadik_dma_set_destadr - low level method for set_dma_speed API
-+ * @channel: DMA channel number
-+ * @dma: DMA channel data structure pointer
-+ * @cycle: sonsidered as destination DMA address
-+ *
-+ * Since ther is no API to program destination DMA address.
-+ * set_dma_speed is used to fulfill this need.
-+ * the function returnes the cycle which finally programs dma->spped
-+ * with destination DMA address for nomadik platform
-+ */
-+static int nomadik_dma_set_destadr(dmach_t channel, dma_t *dma, int cycle)
-+{
-+ /*Speed is used to store destination address*/
-+ return (cycle);
-+}
+
-+/**
-+ * nomadik_dma_interrupt - Interrupt handler for DMA controller
-+ * @irq: interrupt request number
-+ * @desc: irq structure pointer
-+ *
-+ * checks and find out the source DMA channel who generated interrupt
-+ * if interrupt generated is Terminal count then
-+ * process the DMA chanel irq associated with a pipe
-+ * if interrupt generated is Bus_error then
-+ * just acknowledge it.
-+ * free processed transfer lli and schedule the queue
-+ */
-+static void nomadik_dma_interrupt(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
-+{
-+ u32 mask;
-+ volatile struct dma_register *p_dma_reg = (struct dma_register *)desc->chip_data;
-+ volatile struct dmach_register *p_dmach_reg;
-+ struct dma_struct *di_dmachan;
-+ do {
-+ p_dmach_reg = &p_dma_reg->dmach[0];
-+ nmdk_dbg2("dhach addr = %p", p_dmach_reg);
-+ for (mask = 1; mask != 0x100; mask=mask<<1) {
-+ if (p_dma_reg->mis & mask) {
-+ /* To wait for the physical Channel to get disabled(otherwise it may
-+ cause Virtual/Spurious Interrupts) */
-+ while (nomadik_dmach_is_active_n_enabled(p_dmach_reg->cfg)) ;
-+ if (p_dma_reg->tcmis & mask) {
-+ p_dma_reg->tcicr |= mask;
-+ irq = nomadik_dma_channel_of_pipe((void *)p_dmach_reg);
-+ if (irq != 0) {
-+ desc = socdat->dirqdesc + irq;
-+ di_dmachan = socdat->dma_chan + DMACH_FOR_IRQNO(irq);
-+ /*handle dmachanel interrupt callback*/
-+ nmdk_dbg3("ch%d tc intr", DMACH_FOR_IRQNO(irq));
-+ /*flag upper layer to that requested dma is complete*/
-+ if (di_dmachan->active) di_dmachan->active = 0;
-+ desc_handle_irq(irq, desc);
-+ /*free lli of processed request and schedule if any request in queue*/
-+ nomadik_dma_free_procesed_pipe(p_dmach_reg);
-+ }
-+ }
-+ if (p_dma_reg->emis & mask) {
-+ p_dma_reg->eicr |= mask;
-+ nmdk_error("Intr buserr for pipe %08x", (u32)p_dmach_reg);
-+ nomadik_dma_free_procesed_pipe(p_dmach_reg);
-+ }
-+ }
-+ p_dmach_reg++;
-+ }
-+ } while (p_dma_reg->mis != 0);
-+ nmdk_dbg2("intr exit");
-+}
+
-+struct dma_ops nomadik_dma_ops = {
-+ .type = "DMACH:",
-+ .request = nomadik_dma_req,
-+ .free = nomadik_dma_fr,
-+ .enable = nomadik_dma_en,
-+ .disable = nomadik_dma_dis,
-+ .setspeed = nomadik_dma_set_destadr,
-+ .residue = nomadik_dma_residue,
-+};
++ ldr r11, =backup_ram_store
++ mov r10,#0x250
++ add r10, r2, r10
++ str r10, [r11, #0x0]
+
-+/**
-+ * nomadik_dma_probe - driver probe function
-+ *
-+ * checks platfom_data is programmed properly
-+ * ioremaps the DMAC register and updates pointer
-+ * sets DMAC irq handler
-+ * allocates memory for lli pool
-+ * configures DMA channels and DMA channel interrupts
-+ */
-+static int nomadik_dma_probe(struct amba_device *dev, void *data)
-+{
-+ int i, ret;
-+ uint8 dmac;
-+ struct irq_desc *dirq_desc;
-+ struct dma_struct *dmachan, *dmachan_temp;
-+ volatile struct dma_register *p_dma_reg;
-+ struct irqchip *p_dirqchip;
++#ifdef DEEP_SLEEP_DEBUG
++ /*Clean entire DCache using test and clean*/
++clean_dcache_start:
++ mrc p15,0,r15,c7,c14,3
++ bne clean_dcache_start
+
-+ nmdk_dbg_ftrace();
++ /* Invalidate I cache and Dcache */
++ mov r0,#0
++ mcr p15,0,r0,c7,c7,0
+
-+ /* findout dma controller number*/
-+ if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
-+ else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
-+ else {
-+ nmdk_error("invalid dma device");
-+ ret = -EINVAL;
-+ goto res_out;
-+ }
++ /*Drain Write Buffers*/
++ mov r0,#0
++ mcr p15,0,r0,c7,c10,4
++#endif
+
-+ if (! dev->dev.platform_data) {
-+ nmdk_error("platform specific data no initialized for DMAC%d", dmac);
-+ ret = -ENOMEM;
-+ goto res_out;
-+ }
-+/* ret = amba_request_regions(dev, NULL);
-+ if (ret)
-+ goto out;
-+ */
-+ p_dma_reg = (void __iomem *)
-+ ioremap((int)dev->res.start, SZ_4K);
-+ if (!p_dma_reg) {
-+ nmdk_error("ioremap failed for DMAC%d", dmac);
-+ ret = -ENOMEM;
-+ goto res_out;
-+ }
-+ nmdk_dbg("dma_erg prt = %p irq %d", p_dma_reg,dev->irq[0] );
-+ socdat = (struct dma_soc_data *)dev->dev.platform_data;
-+ dmachan = (struct dma_struct *)socdat->dma_chan;
-+ dirq_desc = socdat->dirqdesc;
-+ p_dirqchip = socdat->dirqchip;
-+ dirq_desc[dev->irq[0]].chip_data = (void *)p_dma_reg;
++ /* Storing the enabled values of VIC */
++ ldr r0, =vic_base
++ ldr r0, [r0,#0x0]
+
-+ memset((void *)p_dma_reg, 0, sizeof(struct dma_register)); /*init h/w register to zero*/
-+#ifdef __STN_8810
-+#if (__STN_8810 == 10)
-+ p_dma_reg->cr = 0x01; /*enable DMa controller */
-+#endif
-+#endif
++ ldr r1, [r0,#0xC] /* Interrupt sslection register */
++ ldr r2, [r0, #0x2C]
++ ldr r3, [r0, #0x10] /* Interrupt Enable register */
++ ldr r4, [r0, #0x30]
++ ldr r5, [r0, #0x54] /* Default VAR */
++ stmfd sp!, {r1-r5}
+
-+ set_irq_chained_handler(dev->irq[0], (void *)nomadik_dma_interrupt);
+
-+ if (!(dmac)) {
+
-+ lli_ptr_log = (struct dmach_lli *)dma_alloc_coherent(NULL,
-+ MAX_DMA_LLIS * (sizeof(struct dmach_lli)),
-+ (dma_addr_t *) &lli_ptr_phy,
-+ GFP_DMA | GFP_ATOMIC);
-+ if (lli_ptr_log <= 0) {
-+ nmdk_error("unable to request mem for llis");
-+ ret = -1;
-+ goto bad_dev;
-+ }
-+ nmdk_info("chanel lli physical adr(%08x) logical adr(%08x)", (u32)lli_ptr_phy, (u32)lli_ptr_log);
-+ dmachan_temp = dmachan;
-+ /* dma chanel irq initialization */
-+ for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
-+ /*set_irq_chip(i, &nomadik_dma_chip);*/
-+ set_irq_handler(i, handle_simple_irq);
-+ set_irq_flags(i, IRQF_VALID);
-+ socdat->dirqdesc[i].chip_data= NULL; //&p_dma_reg->dmach[ret];
-+ if (i < MAX_DMA_CHANNELS) p_lli_pipe[DMACH_FOR_IRQNO(i)] = NULL;
-+ /* dma chanel data structure initialization */
-+ dmachan[DMACH_FOR_IRQNO(i)].d_ops = &nomadik_dma_ops;
-+ dmachan[DMACH_FOR_IRQNO(i)].dma_irq = i;
++ ldr r1,[r0,#0x100]
++ ldr r2,[r0,#0x104]
++ ldr r3,[r0,#0x108]
++ ldr r4,[r0,#0x10C]
++ ldr r5,[r0,#0x110]
++ ldr r6,[r0,#0x114]
++ ldr r7,[r0,#0x118]
++ ldr r8,[r0,#0x11C]
++ ldr r9,[r0,#0x120]
++ ldr r10,[r0,#0x124]
++ ldr r11,[r0,#0x128]
++ stmfd sp!,{r1-r11}
+
-+ }
-+ }
-+ nmdk_info("DMA%d Module initialized Ver("DMA_VER")",dmac);
-+ return (0);
++ ldr r1,[r0,#0x12C]
++ ldr r2,[r0,#0x130]
++ ldr r3,[r0,#0x134]
++ ldr r4,[r0,#0x138]
++ ldr r5,[r0,#0x13C]
++ ldr r6,[r0,#0x200]
++ ldr r7,[r0,#0x204]
++ ldr r8,[r0,#0x208]
++ ldr r9,[r0,#0x20C]
++ ldr r10,[r0,#0x210]
++ ldr r11,[r0,#0x214]
++ stmfd sp!,{r1-r11}
+
-+bad_dev:
-+ iounmap(p_dma_reg);
-+res_out:
-+ return (ret);
-+}
+
-+/**
-+ * nomadik_dma_remove - driver remove function
-+ *
-+ * resets DMA channels and DMA channel interrupts configureation
-+ * deallocates memory for lli pool
-+ * resets DMAC irq handler
-+ * frees ioremapped memory
-+ */
-+static int nomadik_dma_remove(struct amba_device *dev)
-+{
-+ uint8 dmac;
-+ int i;
-+ struct irq_desc *dirq_desc;
-+ struct dma_struct *dma_chan;
-+ volatile struct dma_register *p_dma_reg;
-+ struct irqchip *p_dirqchip;
++ ldr r1,[r0,#0x218]
++ ldr r2,[r0,#0x21C]
++ ldr r3,[r0,#0x220]
++ ldr r4,[r0,#0x224]
++ ldr r5,[r0,#0x228]
++ ldr r6,[r0,#0x22C]
++ ldr r7,[r0,#0x230]
++ ldr r8,[r0,#0x234]
++ ldr r9,[r0,#0x238]
++ ldr r10,[r0,#0x23C]
++ stmfd sp!,{r1-r10}
+
-+ nmdk_dbg_ftrace();
+
-+ /* findout dma controller number*/
-+ if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
-+ else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
-+ else {
-+ nmdk_error("invalide dma device");
-+ return(-EINVAL);
-+ }
-+ socdat = dev->dev.platform_data;
-+ dma_chan = (struct dma_struct *)socdat->dma_chan;
-+ dirq_desc = socdat->dirqdesc;
-+ p_dma_reg = dirq_desc[dev->irq[0]].chip_data;
+
-+ p_dirqchip = socdat->dirqchip;
-+ if (!(dmac)) {
-+ for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
-+ //set_irq_chip(i, 0x00);
-+ set_irq_handler(i, handle_bad_irq);
-+ dma_chan[DMACH_FOR_IRQNO(i)].d_ops = NULL;
-+ }
-+ }
+
-+ set_irq_handler(dev->irq[0], handle_bad_irq);
+
-+ dma_free_coherent(NULL,
-+ ((MAX_DMA_CHANNELS*(sizeof(struct dmach_lli))*8)+256),
-+ (void *)lli_ptr_log, (dma_addr_t)lli_ptr_phy );
-+ lli_ptr_phy = lli_ptr_log = NULL;
++ mrc p15,0, r0,c5,c0,0 /* FSR--Domain Fault */
++ mrc p15,0, r1,c5,c0,1 /* FSR--Instruction Fault */
+
-+ iounmap(p_dma_reg);
-+ dirq_desc[dev->irq[0]].chip_data = 0x00;
-+ /*amba_release_regions(dev);*/
++ mrc p15,0, r2,c6,c0,0 /* FAR */
+
-+ nmdk_info("Module removed");
-+ return 0;
-+}
++ mrc p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
++ mrc p15,0, r4,c9,c0,1 /* Read ICache Lockdown */
+
-+static struct amba_id nomadik_dma_dev_ids[] __initdata = {
-+ {
-+ .id = DMA_PER_ID,
-+ .mask = DMA_PER_MASK,
-+ },
-+ {0, 0},
-+};
++ mrc p15,0, r5,c9,c1,0 /* Read Data TLB */
++ mrc p15,0, r6,c9,c1,1 /* Read Instruction TCM region register */
+
-+static struct amba_driver dma_driver = {
-+ .drv = {
-+ .name = "DMA",
-+ },
-+ .id_table = nomadik_dma_dev_ids,
-+ .probe = nomadik_dma_probe,
-+ .remove = nomadik_dma_remove
-+};
++ mrc p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
+
-+static int __init nomadik_dma_init(void)
-+{
-+ return amba_driver_register(&dma_driver);
-+}
++ mrc p15,0, r8,c13,c0,0 /* FCSE--PID */
++ mrc p15,0, r9,c13,c0,1 /* Context-ID */
+
-+static void __exit nomadik_dma_exit(void)
-+{
-+ amba_driver_unregister(&dma_driver);
-+}
++ /* Save all these registers onto the stack */
++ stmfd sp!, {r0-r9}
+
-+module_init(nomadik_dma_init);
-+module_exit(nomadik_dma_exit);
++ /*Move sp to non banked register. sp is not shared in banked modes.*/
++ mov r6, sp
+
-+/* Module parameters */
++ /* Store the two user mode registers*/
++ sub r6,r6,#0x8
++ stmia r6, {sp, lr}^
++ mov r0,r0
+
-+MODULE_AUTHOR("ST Microelectronics");
-+MODULE_DESCRIPTION("Nomadik DMA Controllers (0 and 1)");
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/fsmc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/fsmc.c
---- linux-2.6.20/arch/arm/mach-nomadik/fsmc.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/fsmc.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,113 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/fsmc.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
++ /* Save current mode with interrupts disabled*/
++ mrs r7, cpsr
++ stmfd r6!, {r7}
++ bic r7,r7,#0xf
+
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <asm/io.h>
-+#include <asm/types.h>
-+#include <asm/hardware.h>
-+#include <asm/arch/fsmc.h>
++ /* move the first par from r12 to r3 */
++ mov r3,r12
+
-+struct fsmc_nomadik_info {
-+ unsigned char __iomem *fsmc_reg;
-+};
++ /** Following are the registers that are used
++ R6:- Stack Pointer
++ R7:- CPSR Value [IRQ Disabled , FIQ Disabled, Mode bit Cleared]
++ R8:- Virtual Address of Backup SRAM (0xA0010250)
++ R9:- UART1 Base Register [Debug Device Base Register]
++ R10:- MPMC Base Register
++ R11:- SRC Base Register
++ R12:- PMU Base Register
++ */
+
-+static int nomadik_fsmc_probe(struct platform_device *pdev)
-+{
-+ struct fsmc_platform_data *pdata = pdev->dev.platform_data;
-+ struct fsmc_nomadik_info *data = NULL;
-+ struct resource *res = NULL;
-+ if (!pdata->init) {
-+ printk("FSMC ::: platform init() function is not present\n");
-+ return (-1);
-+ }
++ ldr r8,=backup_ram_store
++ ldr r8, [r8,#0]
+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ ldr r9,=uart1_base
++ ldr r9, [r9,#0]
+
-+ data = kzalloc(sizeof(struct fsmc_nomadik_info), GFP_KERNEL);
-+ data->fsmc_reg = ioremap(res->start, res->end - res->start + 1);
-+ platform_set_drvdata(pdev, data);
++ ldr r10,=mpmc_base
++ ldr r10, [r10,#0]
+
-+ /*do platform specific fsmc init */
-+ return (pdata->init());
-+}
++ ldr r11,=src_base
++ ldr r11, [r11,#0]
+
-+/*
-+ * Clean up routine
-+ */
-+static int nomadik_fsmc_remove(struct platform_device *pdev)
-+{
-+ struct fsmc_nomadik_info *data = NULL;
++ ldr r12,=pmu_base
++ ldr r12, [r12,#0]
+
-+ data = platform_get_drvdata(pdev);
-+ if(data){
-+ iounmap(data->fsmc_reg);
-+ kfree(data);
-+ }
-+ return 0;
-+}
++ /*Store the jump back address at this location (physical Address) */
++ ldr r0, =backup_ram_base
++ ldr r0, [r0,#0]
+
-+#ifdef CONFIG_PM
++ ldr r1, =after_deep_sleep
++ mov r2, #0xC0000000
++ sub r1, r1, r2 /* Change from VA to PA */
+
-+#define FSMC_REG_SIZE 0x78
-+static char vect_fsmc[FSMC_REG_SIZE];
-+int nomadik_fsmc_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+ struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
-+ printk("nomadik_fsmc_suspend: called......\n");
-+ memcpy(vect_fsmc, data->fsmc_reg, FSMC_REG_SIZE);
-+ return 0;
-+}
++ str r1, [r0]
+
-+int nomadik_fsmc_resume(struct platform_device *pdev)
-+{
-+ struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
-+ printk("nomadik_fsmc_resume: called......\n");
-+ memcpy(data->fsmc_reg, vect_fsmc, FSMC_REG_SIZE);
++ /*Enter FIQ mode-Interrupt disabled and save the banked registers*/
++ orr r0,r7,#0x1
++ msr cpsr_cxsf,r0
+
-+ return 0;
-+}
++ mrs r0,spsr
++ stmfd r6!, {r0,r8-r14} /* store r8 to r14 and spsr */
+
-+#else
-+#define nomadik_fsmc_suspend NULL
-+#define nomadik_fsmc_resume NULL
++ /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
++ orr r0,r7,#0x2
++ msr cpsr_cxsf,r0 /* enter IRQ mode with IRQ/FIQ disable */
+
-+#endif
++ mrs r0,spsr
++ stmfd r6!, {r0,r13,r14}
+
-+static struct platform_driver nomadik_fsmc_driver = {
-+ .probe = nomadik_fsmc_probe,
-+ .remove = nomadik_fsmc_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "NOMADIK-FSMC",
-+ },
-+ .suspend = nomadik_fsmc_suspend,
-+ .resume = nomadik_fsmc_resume,
-+};
+
-+static int __init nomadik_fsmc_init(void)
-+{
-+ return platform_driver_register(&nomadik_fsmc_driver);
-+}
++ /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
++ orr r0,r7,#0x7
++ msr cpsr_cxsf,r0
+
-+module_init(nomadik_fsmc_init);
-+static void __exit nomadik_fsmc_exit(void)
-+{
-+ platform_driver_unregister(&nomadik_fsmc_driver);
-+ return;
-+}
++ mrs r0,spsr
++ stmfd r6!, {r0,r13,r14}
+
-+module_exit(nomadik_fsmc_exit);
+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
-+MODULE_DESCRIPTION("FSMC driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/gpio.c ../new/linux-2.6.20/arch/arm/mach-nomadik/gpio.c
---- linux-2.6.20/arch/arm/mach-nomadik/gpio.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/gpio.c 2008-09-16 23:41:14.000000000 +0530
-@@ -0,0 +1,916 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/gpio.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#define GPIO_VER "2.1.0"
++ /*Enter Undef Mode-IRQ/FIQ disable. Save r13,r14 and spsr */
++ orr r0,r7,#0xB
++ msr cpsr_cxsf,r0
+
-+#include <linux/kernel_stat.h>
-+#include <linux/smp.h>
-+#include <linux/spinlock.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/device.h>
-+#include <linux/signal.h>
-+#include <linux/amba/bus.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/interrupt.h>
-+#include <asm/hardware.h>
-+#include <asm/mach/irq.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/debug.h>
++ mrs r0,spsr
++ stmfd r6!, {r0,r13,r14}
+
-+#define GPIO_NAME "GPIO"
+
-+#ifndef GPIO_DEBUG
-+#define GPIO_DEBUG 0
-+#endif
++ /*Store the top of stack [VA] in the Scratch-Pad Register*/
++ str r6,[r12,#0x14]
+
-+#define NMDK_DEBUG GPIO_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX GPIO_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++ /*Go back in SVC mode*/
++ orr r0,r7,#0x3
++ msr cpsr_cxsf,r0
+
-+const char *gpio_block_name[4] = {
-+ "GPIO_Block0", "GPIO_Block1", "GPIO_Block2", "GPIO_Block3",
-+};
++ /* Store MMU registers */
++ /*Domain Register on Back-up RAM structure*/
++ mrc p15,0,r0,c3,c0,0
++ str r0,[r8]
+
-+static spinlock_t altfun_lock = SPIN_LOCK_UNLOCKED;
-+static spinlock_t pinconf_lock = SPIN_LOCK_UNLOCKED;
-+static struct gpio_soc *socdat = NULL; /*soc specific data ptr */
-+extern struct irq_desc irq_desc[]; /* maintain interrupt info */
++ /*TTB Register*/
++ mrc p15,0,r0,c2,c0,0
++ str r0,[r8,#0x4]
+
-+#define CHK_VALID_CALL if (! socdat) { \
-+ nmdk_error("called %s before initilization", __FUNCTION__); \
-+ return(-EINVAL); \
-+ }
++ /*MMU Enable Register*/
++ mrc p15,0,r0,c1,c0,0
++ str r0,[r8,#0x8]
+
-+#define CHK_VALID_PIN(pin) if (irq_desc[IRQNO_GPIO(pin)].action) {\
-+ nmdk_error("%s failed, gpio%d used by irq %d", __FUNCTION__, pin , IRQNO_GPIO(pin));\
-+ return -EINVAL;\
-+ }
++ /* Virtual Address of MMU Enable*/
++ adr r0,mmu_enabled
++ str r0,[r8,#0xC]
+
-+static char *nomadik_gpio_owner(gpio_pin pin_id)
-+{
-+ if (irq_desc[IRQNO_GPIO(pin_id)].action) {
-+ return (char *)irq_desc[IRQNO_GPIO(pin_id)].action->name;
-+ }
-+ if (irq_desc[IRQNO_GPIO(pin_id)].chip_data) {
-+ return (char *)irq_desc[IRQNO_GPIO(pin_id)].chip_data;
-+ }
-+ return (0);
-+}
+
-+/**
-+ * nomadik_gpio_chkwr_permission - checks pin permission for write operation
-+ */
-+static int nomadik_gpio_chkwr_permission(gpio_pin pin_id, char *dev_name)
-+{
-+ char *pin_owner = nomadik_gpio_owner(pin_id);
-+ if (!pin_owner) {
-+ nmdk_error("pin %d not configured", pin_id);
-+ return -1;
-+ }
-+ if (pin_owner != dev_name)
-+ if (!strcmp(pin_owner, dev_name)) {
-+ nmdk_error("pin %d not owned by %s", pin_id, dev_name);
-+ return -1;
-+ }
-+ if (irq_desc[IRQNO_GPIO(pin_id)].action) {
-+ nmdk_error("pin %d used as irq cannot be written", pin_id);
-+ return -1;
-+ }
-+ return 0;
-+}
++ /*Clear the Remap bit from SRC-Register*/
++ ldr r0,[r11]
++ bic r0,r0,#0x100
++ str r0,[r11]
+
-+/*
-+ * Static Function declarations
-+ */
-+static gpio_error gpio_setpinconfig(gpio_pin pin_id, gpio_config * config)
-+{
-+ unsigned long flags;
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
-+ gpio_error gpio_error = GPIO_OK;
++ /*Enable the Mode Status Register*/
++ mov r0,#0
++ str r0,[r11,#0x8]
+
-+ nmdk_dbg_ftrace();
-+ spin_lock_irqsave(&pinconf_lock, flags);
-+ if (config->dev_name)
-+ irq_desc[IRQNO_GPIO(pin_id)].chip_data = config->dev_name;
-+ else
-+ irq_desc[IRQNO_GPIO(pin_id)].chip_data = "unknown";
-+ spin_unlock_irqrestore(&pinconf_lock, flags);
++ /* Clear the PMU bit - for entering the deep sleep mode instead sleep*/
++ ldr r0,[r12]
++ bic r0,r0,#0x10
++ str r0,[r12]
+
-+ switch (config->mode) {
-+ case GPIO_ALTF_A:
-+ p_gpio_register->gpio_afsa |= mask;
-+ p_gpio_register->gpio_afsb &= ~mask;
-+ break;
-+ case GPIO_ALTF_B:
-+ p_gpio_register->gpio_afsa &= ~mask;
-+ p_gpio_register->gpio_afsb |= mask;
-+ break;
-+ case GPIO_ALTF_C:
-+ p_gpio_register->gpio_afsa |= mask;
-+ p_gpio_register->gpio_afsb |= mask;
-+ break;
-+ case GPIO_MODE_SOFTWARE:
-+ p_gpio_register->gpio_afsa &= ~mask;
-+ p_gpio_register->gpio_afsb &= ~mask;
++ /*Store the value of Scratch-Pad Register*/
++ ldr r0,=backup_ram_base_phys
++ ldr r0,[r0,#0x0]
++ str r0,[r12,#0x10]
+
-+ switch (config->direction) {
-+ case GPIO_DIR_INPUT:
-+ p_gpio_register->gpio_dirc = mask;
-+ break;
-+ case GPIO_DIR_OUTPUT:
-+ p_gpio_register->gpio_dirs = mask;
-+ break;
-+ case GPIO_DIR_LEAVE_UNCHANGED:
-+ break;
-+ default:
-+ return (GPIO_INVALID_PARAMETER);
-+ }
++ /*Program to wake-up in Normal mode*/
++ ldr r0,[r11,#0x4]
++ bic r0,r0,#0xf
++ orr r0,r0,#0x9
++ str r0,[r11,#0x4]
+
-+ if (socdat->dbounce)
-+ gpio_error =
-+ socdat->dbounce(p_gpio_register, mask,
-+ config->debounce,
-+ config->debounce_time);
-+ break;
-+ case GPIO_MODE_LEAVE_UNCHANGED:
-+ break;
-+ default:
-+ return (GPIO_INVALID_PARAMETER);
-+ }
-+ return (gpio_error);
-+}
++ /*Clean entire DCache using test and clean*/
++clean_dcache:
++ mrc p15,0,r15,c7,c10,3
++ bne clean_dcache
+
-+static gpio_error gpio_resetgpiopin(gpio_pin pin_id, char *dev_name)
-+{
-+ unsigned long flags;
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
-+ char *pin_dev_name;
-+ gpio_error gpio_error = GPIO_OK;
++ /*Drain Write Buffers*/
++ mov r0,#0
++ mcr p15,0,r0,c7,c10,4
+
-+ nmdk_dbg_ftrace();
-+ pin_dev_name = nomadik_gpio_owner(pin_id);
-+ if (!pin_dev_name)
-+ return 0;
-+ if (strcmp(dev_name, pin_dev_name)) {
-+ nmdk_error("Unable to free pin%d Current Owner is %s", pin_id,
-+ pin_dev_name);
-+ return (-1);
-+ }
-+ p_gpio_register->gpio_afsa &= ~mask;
-+ p_gpio_register->gpio_afsb &= ~mask; /*software mode*/
-+ p_gpio_register->gpio_dirc = mask; /*input dir*/
-+ if (socdat->dbounce) /*disalbe debounce*/
-+ gpio_error =
-+ socdat->dbounce(p_gpio_register, mask,
-+ GPIO_DEBOUNCE_DISABLE,
-+ (gpio_debounce_time)NULL);
-+ /* mark pin is freed */
++ ldr r0, =L2dummyPointer
++ ldr r0, [r0]
++ mov r1, #0
++ cmp r1, r0
++ stmneia r0!,{r1-r8}
+
-+ spin_lock_irqsave(&pinconf_lock, flags);
-+ irq_desc[IRQNO_GPIO(pin_id)].chip_data = NULL;
-+ spin_unlock_irqrestore(&pinconf_lock, flags);
-+ if (irq_desc[IRQNO_GPIO(pin_id)].action)
-+ irq_desc[IRQNO_GPIO(pin_id)].action->name = NULL;
-+ return (gpio_error);
-+}
++#ifdef CONFIG_L2CACHE_ENABLE
++ v_l2_cache_clean_and_invalidate r0, r1
++ v_l2_cache_sync r0, r1
++ v_l2_cache_disable r0,r1
+
-+gpio_config altfun_pinconfig;
-+static gpio_error gpio_altfunction(gpio_alt_function alt_func,
-+ int which_altfunc, char *dev_name)
-+{
-+ struct gpio_altfun_data *altfun_table = socdat->altfun_tbl;
-+ int max_altfun = socdat->sz_altfun_tbl;
-+ int i, j, start, end;
-+ unsigned long flags;
-+ u8 check_pins = 1; /*first check availability of all gpio pins */
-+ gpio_error error = -1;
++#endif
+
-+ nmdk_dbg_ftrace();
-+ spin_lock_irqsave(&altfun_lock, flags);
-+ for (i = 0; i < max_altfun; i++) {
-+ if (altfun_table[i].altfun != alt_func)
-+ continue;
-+ start = altfun_table[i].start;
-+ end = altfun_table[i].end;
-+ if (start > end) {
-+ j = start;
-+ start = end;
-+ end = j;
-+ }
-+ if (end > GPIO_TOTAL_PINS) {
-+ nmdk_error("range upto pin%d not suported", end);
-+ error = GPIO_INVALID_PARAMETER;
-+ goto exit_altfunc;
-+ }
-+ for (j = start; j <= end; j++) {
-+ if (check_pins) {
-+ if (nomadik_gpio_owner(j) &&
-+ (which_altfunc != GPIO_ALTF_DISABLE)) {
-+ nmdk_error("pin%d not free", j);
-+ error = -1;
-+ goto exit_altfunc;
-+ }
-+ if (!nomadik_gpio_owner(j) &&
-+ (which_altfunc == GPIO_ALTF_DISABLE)) {
-+ nmdk_error
-+ ("Trying to disable free pin%d", j);
-+ error = -1;
-+ goto exit_altfunc;
-+ }
-+ } else {
-+ if (which_altfunc == GPIO_ALTF_FIND) {
-+ altfun_pinconfig.mode =
-+ altfun_table[i].type;
-+ } else {
-+ altfun_pinconfig.mode = which_altfunc;
-+ }
-+ altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
-+ altfun_pinconfig.debounce =
-+ GPIO_DEBOUNCE_DISABLE;
-+ altfun_pinconfig.dev_name = dev_name;
+
-+ if (which_altfunc != GPIO_ALTF_DISABLE) {
-+ error =
-+ gpio_setpinconfig(j,
-+ &altfun_pinconfig);
-+ } else {
-+ error = gpio_resetgpiopin(j, dev_name);
-+ }
-+ if (!error)
-+ continue;
-+ nmdk_error
-+ ("GPIO %d configuration failure (nmdk_error:%d)",
-+ j, error);
-+ error = GPIO_INVALID_PARAMETER;
-+ goto exit_altfunc;
-+ }
-+ }
-+ if (altfun_table[i].cont == 0) {
-+ /*schedule to configure if check sucessfull */
-+ if (check_pins) {
-+ check_pins = 0;
-+ i = -1;
-+ } else {
-+ error = 0;
-+ goto exit_altfunc;
-+ }
-+ }
-+ }
-+ exit_altfunc:
-+ spin_unlock_irqrestore(&altfun_lock, flags);
-+ return (error);
-+}
++ /* Prefetch certain instructions in the cache. */
++ adr r4, cache_prefetch_start
++ adr r5, cache_prefetch_end
++ mvn r1,#0x1F
++ ands r4,r1,r4
++fetch_loop:
++ mcr p15, 0, r4, c7, c13,1
++ cmp r4,r5
++ addls r4, r4, #0x20
++ bls fetch_loop
+
-+/**
-+ * exported functions for other drives
-+ */
+
-+/*
-+ * Get gpio list for /proc/gpio
-+ */
-+int get_gpio_list(char *buf)
-+{
-+ struct gpio_register *p_gpio_register;
-+ uint32 mask;
-+ char *p = buf;
-+ char *gpiofunc;
-+ char *gpio_client;
-+ int i;
++cache_prefetch_start:
++ ldr r10, =mpmc_base
++ ldr r10,[r10,#0x0]
+
-+ CHK_VALID_CALL;
-+ p += sprintf(p, "Pin: %s\t%s\n", "mode", "client");
-+ for (i = 0; i < GPIO_TOTAL_PINS; i++) {
-+ gpio_client = nomadik_gpio_owner(i);
-+ if (gpio_client) {
-+ p_gpio_register = (struct gpio_register *)
-+ get_irq_chip_data(GPIO_PIN2BLKIRQ(i));
-+ mask = 1UL << (i % GPIO_PINS_PER_BLOCK);
-+ if (irq_desc[IRQNO_GPIO(i)].action)
-+ gpiofunc = "Irq";
-+ else if ((p_gpio_register->gpio_afsa & mask)
-+ && (p_gpio_register->gpio_afsb & mask))
-+ gpiofunc = "AltFun_C";
-+ else if ((p_gpio_register->gpio_afsa & mask)
-+ && !(p_gpio_register->gpio_afsb & mask))
-+ gpiofunc = "AltFun_A";
-+ else if (!(p_gpio_register->gpio_afsa & mask)
-+ && (p_gpio_register->gpio_afsb & mask))
-+ gpiofunc = "AltFun_B";
-+ else
-+ gpiofunc = "I/O";
-+ p += sprintf(p, "%3d: %s\t%s\n", i,
-+ gpiofunc, gpio_client);
-+ }
-+ }
-+ return p - buf;
-+}
++/* Check sdram is idle */
++poll_loop:
++ ldr r1,[r10, #0x4]
++ ands r1,r1,#0x1
++ cmp r1,#0
++ bne poll_loop
+
-+int nomadik_gpio_resetpinconfig(gpio_pin pin_id, char *dev_name)
-+{
-+ int error = 0;
++ /*Put SDRAM in self-refresh mode*/
++ ldr r1,[r10, #0x20]
++ bic r1,r1,#0x1
++ orr r1,r1,#0x04
++ str r1,[r10, #0x20]
+
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ CHK_VALID_PIN(pin_id);
++ /*Wait for SDRAM to go in self-refresh*/
++wait:
++ ldr r1,[r10,#0x4]
++ and r1,r1,#0x4
++ cmp r1,#0x0
++ beq wait
+
-+ if (0 != nomadik_gpio_owner(pin_id))
-+ error = gpio_resetgpiopin(pin_id, dev_name);
-+ return (error);
-+}
+
-+int nomadik_gpio_setpinconfig(gpio_pin pin_id, gpio_config * pin_config)
-+{
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ CHK_VALID_PIN(pin_id);
-+ if (!irq_desc[IRQNO_GPIO(pin_id)].action) {
-+ if (nomadik_gpio_owner(pin_id)) {
-+ nmdk_error("pin%d not available.. aquired by %s client",
-+ pin_id, nomadik_gpio_owner(pin_id));
-+ return -1;
-+ }
-+ return (gpio_setpinconfig(pin_id, pin_config));
-+ } else {
-+ nmdk_error("Cannot set gpio%d used by irq %d", pin_id,
-+ IRQNO_GPIO(pin_id));
-+ return -1;
-+ }
-+ return 0;
-+}
+
-+int nomadik_gpio_writepin(gpio_pin pin_id, gpio_data value, char *dev_name)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ CHK_VALID_PIN(pin_id);
-+ if (nomadik_gpio_chkwr_permission(pin_id, dev_name)) return -1;
-+ switch (value) {
-+ case GPIO_DATA_HIGH:
-+ p_gpio_register->gpio_dats = mask;
-+ break;
-+ case GPIO_DATA_LOW:
-+ p_gpio_register->gpio_datc = mask;
-+ break;
-+ default:
-+ nmdk_error("Invalid value passed in %s", __FUNCTION__);
-+ return GPIO_INVALID_PARAMETER;
-+ }
-+ return GPIO_OK;
-+}
++ /*Move system to sleep mode*/
++ ldr r1,[r11]
++ bic r1, r1, #0x7
++ str r1,[r11]
+
-+int nomadik_gpio_readpin(gpio_pin pin_id, gpio_data * p_value)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++goto_sleep:
++ ldr r1,[r11]
++ and r1,r1,#0x78
++ cmp r1,#0x0
++ bne goto_sleep
+
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ if ((p_gpio_register->gpio_dat & mask) != GPIO_ALL_ZERO) {
-+ *p_value = GPIO_DATA_HIGH;
-+ } else {
-+ *p_value = GPIO_DATA_LOW;
-+ }
-+ return GPIO_OK;
-+}
+
-+int nomadik_gpio_readblock(gpio_block_id block_id, uint32 * p_value,
-+ uint32 mask)
-+{
-+ struct gpio_register *p_gpio_register;
++ nop
++ nop
++ nop
++ nop
+
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
-+ return GPIO_INVALID_PARAMETER;
+
-+ if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
-+ p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(block_id -
-+ GPIO_BLOCK_32_BITS_0_TO_31
-+ + IRQ_GPIO0);
-+ *p_value = p_gpio_register->gpio_dat & (mask & GPIO_32BIT_MASK);
+
-+ } else {
-+ p_gpio_register = (struct gpio_register *)
-+ get_irq_chip_data((block_id -
-+ GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
-+ IRQ_GPIO0);
-+ switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
-+ case 0:
-+ *p_value =
-+ (p_gpio_register->gpio_dat & (mask & 0x0000ffff));
-+ break;
-+ case 1:
-+ *p_value =
-+ (p_gpio_register->
-+ gpio_dat & (mask & 0x00ffff00)) >> GPIO_SHIFT8;
-+ break;
-+ case 2:
-+ *p_value =
-+ (p_gpio_register->
-+ gpio_dat & (mask & 0xffff0000)) >> GPIO_SHIFT16;
-+ break;
-+ case 3:
-+ *p_value =
-+ (p_gpio_register->
-+ gpio_dat & (mask & 0xff000000)) >> GPIO_SHIFT24;
-+ p_gpio_register += SZ_4K; /* point next bank */
-+ *p_value |=
-+ (p_gpio_register->
-+ gpio_dat & (mask & 0x000000ff)) << GPIO_SHIFT8;
-+ break;
-+ }
-+ }
-+ return (GPIO_OK);
-+}
+
-+int nomadik_gpio_writeblock(gpio_block_id block_id, uint32 p_value, uint32 mask, char *dev_name)
-+{
-+ struct gpio_register *p_gpio_register;
-+ int i, bankno, testmask;
++/* For deepsleep this much pre-fetch is enough */
++cache_prefetch_end:
++ mov r0, r0
++ mov r0, r0
++ mov r0, r0
++ mov r0, r0
+
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
-+ return GPIO_INVALID_PARAMETER;
+
-+ if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
-+ bankno = block_id * GPIO_PINS_PER_BLOCK;
-+ testmask = 0x01;
-+ for (i = bankno; i < (bankno + GPIO_PINS_PER_BLOCK); i++) {
-+ if ((mask & testmask) &&
-+ (!nomadik_gpio_chkwr_permission(i, dev_name))){
-+ return -1;
-+ }
-+ testmask = 1UL << i;
-+ }
++after_deep_sleep:
++/* Restore the MMU registers */
+
-+ p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(block_id -
-+ GPIO_BLOCK_32_BITS_0_TO_31
-+ + IRQ_GPIO0);
-+ p_gpio_register->gpio_datc =
-+ ~(p_value & (mask & GPIO_32BIT_MASK));
-+ p_gpio_register->gpio_dats = p_value & (mask & GPIO_32BIT_MASK);
+
-+ } else {
-+ bankno = (block_id - GPIO_BLOCK_16_BITS_0_TO_15) * 8;
-+ testmask = 0x01;
-+ for (i = bankno; i < (bankno + (GPIO_PINS_PER_BLOCK / 2)); i++) {
-+ if ((mask & testmask) &&
-+ (!nomadik_gpio_chkwr_permission(i, dev_name))){
-+ return -1;
-+ }
-+ testmask = 1UL << i;
-+ }
-+ p_gpio_register = (struct gpio_register *)
-+ get_irq_chip_data((block_id -
-+ GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
-+ IRQ_GPIO0);
-+ switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
-+ case 0:
-+ p_gpio_register->gpio_datc =
-+ ~(p_value & (mask & 0x0000ffff));
-+ p_gpio_register->gpio_dats =
-+ p_value & (mask & 0x0000ffff);
-+ break;
-+ case 1:
-+ p_gpio_register->gpio_datc =
-+ ~(((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
-+ p_gpio_register->gpio_dats =
-+ (((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
-+ break;
-+ case 2:
-+ p_gpio_register->gpio_datc =
-+ ~(((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
-+ p_gpio_register->gpio_dats =
-+ (((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
-+ break;
-+ case 3:
-+ p_gpio_register->gpio_datc =
-+ ~(((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
-+ p_gpio_register->gpio_dats =
-+ (((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
-+ p_gpio_register += SZ_4K; /* point next bank */
-+ p_gpio_register->gpio_datc =
-+ ~(p_value & (mask & 0x000000ff));
-+ p_gpio_register->gpio_dats =
-+ p_value & (mask & 0x000000ff);
-+ break;
-+ }
-+ }
-+ return (GPIO_OK);
-+}
+
-+int nomadik_gpio_altfuncenable(gpio_alt_function altfunc, char *dev_name)
-+{
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
-+}
++ ldr r8,=backup_ram_store_phys
++ mov r9, #0xC0000000
++ sub r8, r8, r9 /* Change from VA to PA */
++ ldr r8, [r8,#0]
+
-+int nomadik_gpio_altfuncdisable(gpio_alt_function altfunc, char *dev_name)
-+{
-+ nmdk_dbg_ftrace();
-+ CHK_VALID_CALL;
-+ return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
-+}
+
-+EXPORT_SYMBOL(nomadik_gpio_setpinconfig);
-+EXPORT_SYMBOL(nomadik_gpio_resetpinconfig);
-+EXPORT_SYMBOL(nomadik_gpio_writepin);
-+EXPORT_SYMBOL(nomadik_gpio_readpin);
-+EXPORT_SYMBOL(nomadik_gpio_readblock);
-+EXPORT_SYMBOL(nomadik_gpio_writeblock);
-+EXPORT_SYMBOL(nomadik_gpio_altfuncenable);
-+EXPORT_SYMBOL(nomadik_gpio_altfuncdisable);
+
-+/**
-+ * Interrupt handling functions
-+ */
-+static void nomadik_gpio_intrenable(struct gpio_register *p_gpio_register,
-+ uint32 mask, uint32 type)
-+{
-+ if (socdat->irqen) {
-+ socdat->irqen(p_gpio_register, mask, type);
-+ } else {
-+ nmdk_error("irqen SOC specific function not configured");
-+ }
-+}
++out_of_sleep:
++ /*Domain Register*/
++ ldr r0,[r8, #0x0]
++ mcr p15,0,r0,c3,c0,0
+
-+static void nomadik_gpio_intrdisable(struct gpio_register *p_gpio_register,
-+ uint32 mask)
-+{
-+ if (socdat->irqdis)
-+ socdat->irqdis(p_gpio_register, mask);
-+ else {
-+ nmdk_error("irqdis SOC specific function not configured");
-+ }
-+}
-+/**
-+ * @flag if 1 means enable, 0 means disable
-+ */
-+int nomadik_gpio_wakeupconfig(unsigned int irq, unsigned int flag)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
-+ if (flag)
-+ p_gpio_register->gpio_fwimsc |= mask;
-+ else
-+ p_gpio_register->gpio_fwimsc &= (~mask);
-+ return 0;
-+}
-+void nomadik_gpio_slpmreg_config(gpio_pin pin_id)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
-+ p_gpio_register->gpio_slpm |= mask;
-+}
++ /*TTB Register*/
++ ldr r0,[r8,#0x4]
++ mcr p15,0,r0,c2,c0,0
+
-+static void nomadik_gpio_mask(unsigned int irq)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
+
-+ nmdk_dbg_ftrace();
-+ nomadik_gpio_intrdisable(p_gpio_register, mask);
-+}
++ /* Virtual Address of mmu_enabled*/
++ ldr r4, [r8, #0xC]
+
-+static void nomadik_gpio_unmask(unsigned int irq)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
++ /*MMU Enable Register*/
++ ldr r1, [r8,#0x8]
++ mcr p15,0,r1,c1,c0,0
+
-+ nmdk_dbg_ftrace();
-+ if (!irq_desc[irq].handler_data) {
-+ nmdk_info
-+ ("for irq%d, configuruing default type as rising edge",
-+ irq);
-+ irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
-+ }
-+ nomadik_gpio_intrenable(p_gpio_register, mask,
-+ (uint32) irq_desc[irq].handler_data);
-+}
++ mov pc,r4
++ mov r0, r0
++ mov r0, r0
++ mov r0, r0
++ mov r0, r0
+
-+static void nomadik_gpio_intrack(unsigned int irq)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
+
-+ nmdk_dbg_ftrace();
-+ p_gpio_register->gpio_ic = mask;
-+}
+
-+/*
-+ * callback function for gpio specific set_irq_type sys call
-+ * This function will be called in the context of request_irq also
-+ */
-+static int nomadik_gpio_intrsettype(unsigned int irq, unsigned int type)
-+{
-+ gpio_config settype_config;
-+ char *client_name = nomadik_gpio_owner(GPIO_PIN_FOR_IRQ(irq));
-+ int ret;
++mmu_enabled:
+
-+ nmdk_dbg_ftrace();
-+ type&=SA_TRIGGER_MASK;
-+ /* mistake proofing for invalid entry incase if you try to configure
-+ * gpiopin interrupt for priority/fiq
-+ */
-+ if ( (type == SA_TRIGGER_MASK) ||
-+ (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_RISING)) ||
-+ (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_FALLING)) ||
-+ (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH))) {
-+ nmdk_error("Invalid IRQ type requested for irq%d", irq);
-+ return -1;
-+ }
-+ if (!irq_desc[irq].action) {
-+ nmdk_error("Trying to set type for unrequested irq%d", irq);
-+ }
-+ if (irq_desc[irq].handler_data) {
-+ nmdk_info("irq %d type already set by %s", irq,
-+ client_name);
-+ return (0);
-+ }
-+ settype_config.mode = GPIO_MODE_SOFTWARE;
-+ settype_config.direction = GPIO_DIR_INPUT;
-+ settype_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+ settype_config.dev_name = client_name;
-+ ret = gpio_setpinconfig(GPIO_PIN_FOR_IRQ(irq), &settype_config);
-+ if (ret < 0) {
-+ nmdk_error("Error in setting irq %d (err %d)", irq, ret);
-+ return (ret);
-+ }
-+ nmdk_dbg("set_irq_type =%d", type);
-+ if (type) {
-+ irq_desc[irq].handler_data = (void *)(type & SA_TRIGGER_MASK);
-+ } else {
-+ nmdk_info
-+ ("%s Configuring default irq type to SA_TRIGGER_RISING",
-+ __FUNCTION__);
-+ irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
-+ }
-+ if ((SA_TRIGGER_RISING == (int)irq_desc[irq].handler_data) ||
-+ (SA_TRIGGER_FALLING == (int)irq_desc[irq].handler_data))
-+ irq_desc[irq].handle_irq = handle_edge_irq;
-+ else if ((SA_TRIGGER_LOW == (int)irq_desc[irq].handler_data) ||
-+ (SA_TRIGGER_HIGH == (int)irq_desc[irq].handler_data))
-+ irq_desc[irq].handle_irq = handle_level_irq;
-+ /* Standard api call set_irq_handler() cannot be used from
-+ the contest of set_irq_type... deadlock occures */
++#ifdef DEEP_SLEEP_DEBUG
++ ldr r9, =uart1_base
++ ldr r9, [r9,#0]
++#endif
+
-+ return (GPIO_OK);
-+}
++ ldr r11, =src_base
++ ldr r11, [r11,#0]
++ ldr r12, =pmu_base
++ ldr r12, [r12,#0]
++ ldr r10, =mpmc_base
++ ldr r10, [r10,#0]
+
-+/**
-+ * callback function for enable_irq_wake and disable_irq_wake system calls
-+ *
-+ * @flag if 1 means enable, 0 means disable
-+ */
-+static int nomadik_gpio_intrwake(unsigned int irq, unsigned int flag)
-+{
-+ struct gpio_register *p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
-+ unsigned int type = (uint32) irq_desc[irq].handler_data;
+
-+ if (socdat->irqwake) {
-+ if (!type)
-+ type = SA_TRIGGER_RISING;
-+ if (!flag)
-+ type = 0xff; /* to disable wakeup irq */
-+ socdat->irqwake(p_gpio_register, mask, type);
-+ } else {
-+ nmdk_error("irqwake SOC specific function not configured");
-+ return (-1);
-+ }
-+ return (0);
-+}
+
-+struct irq_chip nomadik_gpio_chip = {
-+ .ack = nomadik_gpio_intrack,
-+ .mask = nomadik_gpio_mask,
-+ .unmask = nomadik_gpio_unmask,
-+ .set_type = nomadik_gpio_intrsettype,
-+ .set_wake = nomadik_gpio_intrwake,
-+};
++ /* Move system to Normal Mode */
++ ldr r1,[r11]
++ orr r1,r1,#0x4
++ bic r1,r1,#0x3
++ str r1,[r11]
+
-+static void nomadik_gpio_intr_handler(u32 irq, struct irq_desc *desc)
-+{
-+ struct gpio_register *p_gpio_reg =
-+ (struct gpio_register *)get_irq_chip_data(irq);
-+ unsigned long mis = p_gpio_reg->gpio_mis;
+
-+ nmdk_dbg2("%d intr desc %p", (irq - IRQ_GPIO0), desc);
-+ irq = IRQNO_GPIO((irq - IRQ_GPIO0) * GPIO_PINS_PER_BLOCK);
-+ desc = irq_desc + irq;
-+ while (mis) {
-+ if (mis & 1) {
-+ nmdk_dbg2("handling irq %d", irq);
-+ desc->handle_irq(irq, desc);
-+ }
-+ irq++;
-+ desc++;
-+ mis >>= 1;
-+ }
-+}
++ /*Wait for the system to move in normal mode*/
++wait_norm1:
++ ldr r0,[r11, #0x0]
++ and r0,r0,#0x78
++ cmp r0, #0x20
++ bne wait_norm1
+
-+static int nomadik_gpio_probe(struct amba_device *dev, void *id)
-+{
-+ int i, ret;
-+ struct gpio_register *p_gpio_register;
+
-+ nmdk_dbg_ftrace();
++ /* Remove the chip from Interrupt mode */
++ ldr r0,[r11, #0x4]
++ bic r0,r0,#0x1
++ str r0,[r11, #0x4]
+
-+ socdat = dev->dev.platform_data;
++ /* Clear the interrupt mode status bit*/
++ mov r0, #0x0
++ str r0, [r11, #0x8]
+
-+ if (!socdat) {
-+ nmdk_error("platform_data struct for %s not initialized",
-+ dev->dev.bus_id);
-+ ret = -1;
-+ goto out;
-+ }
-+ ret = amba_request_regions(dev, NULL);
-+ if (ret)
-+ goto out;
++ /* For CLCD Refresh issue */
++ ldr r1, =0x00000005 /* Loading the value with timeout so as to avoid flickering on CLCD */
++ str r1, [r10, #0x408]
+
-+ for (i = 0; i < (dev->irq[1] - dev->irq[0]); i++) {
-+ set_irq_chip_data((i + dev->irq[0]),
-+ (void *)ioremap((int)dev->res.start +
-+ (i * SZ_4K), SZ_4K));
+
-+ p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
++ /* Stack Restoration Routine */
++ ldr r6,[r12,#0x14]
+
-+ if (!p_gpio_register) {
-+ ret = -ENOMEM;
-+ goto res_out;
-+ }
++ /* Store the value of cpsr in r7*/
++ mrs r7,cpsr
++ orr r7,r7,#0xC0 /*Not Needed*/
++ bic r7,r7,#0xf
+
-+ set_irq_chained_handler((i + dev->irq[0]),
-+ nomadik_gpio_intr_handler);
-+ }
++ /*Move to undef mode and restore everything*/
++ orr r0,r7,#0xB
++ msr cpsr_cxsf,r0
+
-+ for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
-+ set_irq_chip(i, &nomadik_gpio_chip);
-+ set_irq_handler(i, handle_level_irq);
-+ set_irq_flags(i, IRQF_VALID);
-+ set_irq_chip_data(i, NULL); /*clear gpio client name */
-+ irq_desc[i].handler_data = NULL; /*clear gpio irq_type */
-+ }
++ ldmfd r6!, {r0,r13,r14}
++ msr spsr_cxsf,r0
+
-+ nmdk_info("Module initialized Ver(" GPIO_VER ")");
-+ return 0;
++ /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
++ orr r0,r7,#0x7
++ msr cpsr_cxsf,r0
+
-+ res_out:
-+ for (; 0 == i; i--) {
-+ p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
++ ldmfd r6!, {r0,r13,r14}
++ msr spsr_cxsf,r0
+
-+ set_irq_handler((i + dev->irq[0]), handle_bad_irq);
-+ if (p_gpio_register)
-+ iounmap((void __iomem *)p_gpio_register);
-+ set_irq_chip_data((i + dev->irq[0]), NULL);
++ /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
++ orr r0,r7,#0x2
++ msr cpsr_cxsf,r0
+
-+ }
-+ amba_release_regions(dev);
-+ out:
-+ return (ret);
-+}
++ ldmfd r6!, {r0,r13,r14}
++ msr spsr_cxsf,r0
+
-+static int nomadik_gpio_remove(struct amba_device *dev)
-+{
-+ int i;
+
-+ nmdk_dbg_ftrace();
-+ for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
-+ set_irq_chip(i, NULL);
-+ set_irq_chip_data(i, NULL);
-+ }
++ /*Enter FIQ mode-Interrupt disabled and save the banked registers. Save: r8-r14 and spsr*/
++ orr r0,r7,#0x1
++ msr cpsr_cxsf,r0
+
-+ for (i = dev->irq[0]; i < dev->irq[1]; i++) {
-+ set_irq_handler(i, handle_bad_irq);
-+ iounmap((void __iomem *)get_irq_chip_data(i));
-+ set_irq_chip_data(i, NULL);
-+ }
-+ amba_release_regions(dev);
-+ socdat = NULL;
-+ nmdk_info("Module removed");
-+ return 0;
-+}
++ ldmfd r6!, {r0,r8-r14}
++ msr spsr_cxsf,r0
+
-+#if (defined CONFIG_PM && defined __STN_8815)
-+static int nomadik_gpio_suspend(struct amba_device *dev, pm_message_t state)
-+{
-+ unsigned int i;
-+ struct gpio_register *p_gpio_register;
-+ struct gpio_pm_context *gpio_pm;;
++ /* Here we will restore our cpsr..IRQ/FIQ Disabled*/
++ ldr r0, [r6]
++ msr cpsr_cxsf, r0
++ add r6, r6,#4
+
-+ nmdk_dbg_ftrace();
-+ dev->dev.driver_data =
-+ kmalloc(sizeof(struct gpio_pm_context) * GPIO_BLOCKS_COUNT,
-+ GFP_KERNEL);
-+ gpio_pm = (struct gpio_pm_context *)dev->dev.driver_data;
-+ if (!gpio_pm) {
-+ nmdk_error("Unable to alocate memory %s failed...",
-+ __FUNCTION__);
-+ }
-+ for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
-+ p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
-+ gpio_pm[i].slpm = p_gpio_register->gpio_slpm;
-+ gpio_pm[i].rwimsc = p_gpio_register->gpio_rwimsc;
-+ gpio_pm[i].fwimsc = p_gpio_register->gpio_fwimsc;
-+ gpio_pm[i].rimsc = p_gpio_register->gpio_rimsc;
-+ gpio_pm[i].fimsc = p_gpio_register->gpio_fimsc;
-+ }
-+ return 0;
-+}
++ /*Now only two user-mode registers are left*/
++ ldmia r6,{sp, lr}^
++ mov r0,r0
++ add r6,r6,#8
+
-+static int nomadik_gpio_resume(struct amba_device *dev)
-+{
-+ unsigned int i;
-+ struct gpio_register *p_gpio_register;
-+ struct gpio_pm_context *gpio_pm =
-+ (struct gpio_pm_context *)dev->dev.driver_data;
++ /*Restore sp*/
++ mov sp,r6
+
-+ nmdk_dbg_ftrace();
-+ for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
-+ p_gpio_register =
-+ (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
-+ p_gpio_register->gpio_slpm = gpio_pm[i].slpm;
-+ p_gpio_register->gpio_rwimsc = gpio_pm[i].rwimsc;
-+ p_gpio_register->gpio_fwimsc = gpio_pm[i].fwimsc;
-+ p_gpio_register->gpio_rimsc = gpio_pm[i].rimsc;
-+ p_gpio_register->gpio_fimsc = gpio_pm[i].fimsc;
-+ }
-+ kfree(gpio_pm);
-+ return 0;
-+}
-+#else
-+#define nomadik_gpio_suspend NULL
-+#define nomadik_gpio_resume NULL
-+#endif
+
-+static struct amba_id nomadik_gpio_ids[] = {
-+ {
-+ .id = GPIO_PER_ID,
-+ .mask = GPIO_PER_MASK,
-+ },
-+ {0, 0},
-+};
++ /*ReStore the remaining items*/
++ ldmfd sp!, {r0-r9}
+
-+static struct amba_driver gpio_driver = {
-+ .drv = {
-+ .owner = THIS_MODULE,
-+ .name = "gpio",
-+ },
-+ .probe = nomadik_gpio_probe,
-+ .remove = nomadik_gpio_remove,
-+ .suspend = nomadik_gpio_suspend,
-+ .resume = nomadik_gpio_resume,
-+ .id_table = nomadik_gpio_ids,
-+};
++ mcr p15,0, r0,c5,c0,0 /*FSR--Domain Fault */
++ mcr p15,0, r1,c5,c0,1 /*FSR--Instruction Fault */
+
-+static int __init nomadik_gpio_init(void)
-+{
-+ return amba_driver_register(&gpio_driver);
-+}
++ mcr p15,0, r2,c6,c0,0 /* FAR */
+
-+static void __exit nomadik_gpio_exit(void)
-+{
-+ amba_driver_unregister(&gpio_driver);
-+}
++ mcr p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
++ mcr p15,0, r4,c9,c0,1 /* Read ICache Lockdown */
+
-+EXPORT_SYMBOL(nomadik_gpio_intrsettype);
-+EXPORT_SYMBOL(nomadik_gpio_mask);
-+EXPORT_SYMBOL(nomadik_gpio_unmask);
++ mcr p15,0, r5,c9,c1,0 /* Read Data TLB */
++ mcr p15,0, r6,c9,c1,1 /* Read Instruction Lockdown */
+
-+module_init(nomadik_gpio_init);
-+module_exit(nomadik_gpio_exit);
++ mcr p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
+
-+MODULE_AUTHOR("Prafulla WADASKAR <prafulla.wadaskar@st.com>");
-+MODULE_DESCRIPTION("Nomadik GPIO Driver");
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/irq.c ../new/linux-2.6.20/arch/arm/mach-nomadik/irq.c
---- linux-2.6.20/arch/arm/mach-nomadik/irq.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/irq.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,231 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/irq.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Author : Prafulla WADASKAR <prafulla.wadaskar@st.com>
-+ * Reference : Documentation/arm/STM-Nomadik/irq_usrguide.txt
-+ */
-+#include <linux/kernel_stat.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/list.h>
-+#include <linux/timer.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/mach/irq.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/debug.h>
++ mcr p15,0, r8,c13,c0,0 /* FCSE--PID */
++ mcr p15,0, r9,c13,c0,1 /* Context-ID */
+
-+#define VIC_VER "2.0.0"
-+#define VIC_NAME "VIC"
+
-+#ifndef VIC_DEBUG
-+#define VIC_DEBUG 0
-+#endif
+
-+#define NMDK_DEBUG VIC_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX VIC_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
+
-+struct vic_basic_registers {
-+ u32 irqsr; /* IRQ Status*/
-+ u32 fiqsr; /* FIQ Status*/
-+ u32 ris; /* Raw Interrupt status*/
-+ u32 isel; /* Interrupt select*/
-+ u32 iens; /* Interrupt enable set*/
-+ u32 ienc; /* Interrupt enable clear*/
-+ u32 swisr; /* Software interrupt*/
-+ u32 swicr; /* Software interrupt clear*/
-+};
+
-+struct vic_register {
-+ struct vic_basic_registers bank[(MAXIRQNUM/32) +1];
-+ u32 per; /* Protection enable*/
-+#if defined(__STN_8815)
-+ u32 reserved_1[(0x50 - 0x44) >> 2]; /* Reserved*/
-+ u32 isr_var; /* ISR Vector address*/
-+ u32 isr_dvar; /* ISR Default vector address*/
-+ u32 reserved_2[(0x100 - 0x58) >> 2]; /* Reserved*/
-+#elif defined(__STN_8810)
-+ u32 reserved_1[(0x30 - 0x24) >> 2]; /* Reserved*/
-+ u32 isr_var; /* ISR Vector address*/
-+ u32 isr_dvar; /* ISR Default vector address*/
-+ u32 reserved_2[(0x100 - 0x38) >> 2]; /* Reserved*/
-+#endif
-+ u32 var[VIC_VECTORED_IRQ_NUM]; /* Vector address 0-15*/
-+ u32 reserved_3[(0x200 - 0x140) >> 2]; /* Reserved*/
-+ u32 vcr[VIC_VECTORED_IRQ_NUM]; /* Vector control 0-15*/
-+ u32 reserved_4[(0x300 - 0x240) >> 2]; /* Reserved*/
-+ u32 itcr; /* Test Control register*/
-+ u32 itip_1; /* Test input nVICIRQIN/nVICFIQIN*/
-+ u32 itip_2; /* Test input VICVECADDRIN*/
-+ u32 itop_1; /* Test output nVICIRQ/nVICFIQ*/
-+ u32 itop_2; /* Test output VICVECADDROUT*/
-+ u32 reserved_5[(0xFE0 - 0x314) >> 2]; /* Reserved*/
-+ u32 periph_id_0; /* Peripheral id: bits 7:0*/
-+ u32 periph_id_1; /* Peripheral id: bits 15:8*/
-+ u32 periph_id_2; /* Peripheral id: bits 23:16*/
-+ u32 periph_id_3; /* Peripheral id: bits 31:24*/
-+ u32 pcell_id_0; /* PrimeCell id: bits 7:0*/
-+ u32 pcell_id_1; /* PrimeCell id: bits 15:8*/
-+ u32 pcell_id_2; /* PrimeCell id: bits 23:16*/
-+ u32 pcell_id_3; /* PrimeCell id: bits 31:24*/
-+};
+
-+extern struct irq_desc irq_desc[]; /* interrupt description table */
-+static volatile struct vic_register *p_vic_register =
-+ (struct vic_register *)IO_ADDRESS(NOMADIK_IC_BASE);
++ /* ReStoring the enabled values of VIC */
++ ldr r0, =vic_base
++ ldr r0, [r0,#0]
+
-+static int nomadik_vic_set_type(unsigned int irq, unsigned int type);
-+static DEFINE_SPINLOCK(vic_lock);
++ ldmfd sp!,{r1-r10}
++ str r1,[r0,#0x218]
++ str r2,[r0,#0x21C]
++ str r3,[r0,#0x220]
++ str r4,[r0,#0x224]
++ str r5,[r0,#0x228]
++ str r6,[r0,#0x22C]
++ str r7,[r0,#0x230]
++ str r8,[r0,#0x234]
++ str r9,[r0,#0x238]
++ str r10,[r0,#0x23C]
+
-+static void nomadik_vic_priority_mask(unsigned int irq)
-+{
-+ u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
-+ u32 mask = 1UL<<irq%32;
-+ /*
-+ * Reading the VIC_VAR register updates the interrupt controllers
-+ * hardware priority register to mask lower priority interrupts.
-+ * reading is done in entry-macro.S
-+ */
-+ p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
-+ p_vic_register->bank[irq/32].ienc |= mask;
-+}
+
-+static void nomadik_vic_priority_unmask(unsigned int irq)
-+{
-+ u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
-+ u32 mask = 1UL<<irq%32;
++ ldmfd sp!,{r1-r11}
++ str r1,[r0,#0x12C]
++ str r2,[r0,#0x130]
++ str r3,[r0,#0x134]
++ str r4,[r0,#0x138]
++ str r5,[r0,#0x13C]
++ str r6,[r0,#0x200]
++ str r7,[r0,#0x204]
++ str r8,[r0,#0x208]
++ str r9,[r0,#0x20C]
++ str r10,[r0,#0x210]
++ str r11,[r0,#0x214]
+
-+ p_vic_register->vcr[priority_level] |= VIC_VECTORED_IRQ_EN;
-+ p_vic_register->bank[irq/32].iens |= mask;
-+ /*
-+ * Write to the VIC_VAR register.
-+ * This clears the respective interrupt in the internal interrupt
-+ * priority hardware.
-+ */
-+ p_vic_register->isr_var = (u32)NULL;
-+}
+
-+static struct irq_chip nomadik_vic_priority_chip = {
-+ .ack = nomadik_vic_priority_mask,
-+ .mask = nomadik_vic_priority_mask,
-+ .unmask = nomadik_vic_priority_unmask,
-+ .set_type = nomadik_vic_set_type
-+};
+
-+static void nomadik_vic_mask(unsigned int irq)
-+{
-+ u32 mask = 1UL<<irq%32;
-+ p_vic_register->bank[irq/32].ienc |= mask;
-+}
++ ldmfd sp!,{r1-r11}
++ str r1,[r0,#0x100]
++ str r2,[r0,#0x104]
++ str r3,[r0,#0x108]
++ str r4,[r0,#0x10C]
++ str r5,[r0,#0x110]
++ str r6,[r0,#0x114]
++ str r7,[r0,#0x118]
++ str r8,[r0,#0x11C]
++ str r9,[r0,#0x120]
++ str r10,[r0,#0x124]
++ str r11,[r0,#0x128]
+
-+static void nomadik_vic_unmask(unsigned int irq)
-+{
-+ u32 mask = 1UL<<irq%32;
-+ p_vic_register->bank[irq/32].iens |= mask;
-+}
++ ldmfd sp!, {r1-r5}
++ str r1, [r0,#0xC] /* Interrupt sslection register */
++ str r2, [r0, #0x2C]
++ str r3, [r0, #0x10] /* Interrupt Enable register */
++ str r4, [r0, #0x30]
++ str r5, [r0, #0x54] /* Default VAR */
+
-+static struct irq_chip nomadik_vic_chip = {
-+ .ack = nomadik_vic_mask,
-+ .mask = nomadik_vic_mask,
-+ .unmask = nomadik_vic_unmask,
-+ .set_type = nomadik_vic_set_type
-+};
+
-+/**
-+ * nomadik_vic_set_type - To enable/disable/change priority logic
-+ *
-+ * callback function for set_irq_type sys call
-+ * This function will be called in the context of request_irq.
-+ * This function is used to configure the interrupt priotity requested
-+ * through request_irq sytem call
-+ *
-+ * This function can be invoked by set_irq_type sys call ,using which
-+ * you can enable/disable/change preprogrammed priority
-+ *
-+ * Note: this function will NOT be invoked if interrupt is requested as
-+ * shared irq (i.e. SA_SHIRQ is specifed during requerst_irq),
-+ */
-+static int nomadik_vic_set_type(unsigned int irq, unsigned int type)
-+{
-+ struct irq_desc *desc;
-+ struct irq_chip *vic_chip;
-+ unsigned long flags;
+
-+ u8 priority_level;
++ /*Clean entire DCache using test and clean*/
++clean_dcache_end:
++ mrc p15,0,r15,c7,c14,3
++ bne clean_dcache_end
+
-+ nmdk_dbg_ftrace();
-+ if (!irq_desc[irq].action) return(-1); /*if irq not configured*/
-+ /*
-+ * Priority logic does not work for interrupt configured with
-+ * SA_TIMER flag, hence exit if SA_TIMER flag is set for irq
-+ */
-+ if (irq_desc[irq].action->flags & IRQF_TIMER) return(-1);
-+ if ((type & SA_NMDK_PRIORITYIRQ) != SA_NMDK_PRIORITYIRQ) return(-1);
-+ /*
-+ * if this function is invoked by set_irq_type call
-+ * then store input type as flags
-+ */
-+ if (type > SA_TRIGGER_MASK) irq_desc[irq].action->flags = type;
-+ /*process irq priority configuration*/
-+ priority_level = (u8)(((irq_desc[irq].action->flags)>>24) & 0x0f);
-+ if (p_vic_register->vcr[priority_level] & VIC_VECTORED_IRQ_EN) {
-+ nmdk_info("priority change for active irq%d", irq);
-+ }
-+ /*configure vic for vectored priority interrupt request*/
-+ p_vic_register->var[priority_level] = irq;
-+ p_vic_register->vcr[priority_level] = irq;
-+ /* configure appropriate chip pointer*/
-+ desc = irq_desc + irq;
-+ if (!priority_level) {
-+ p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
-+ vic_chip = &nomadik_vic_chip;
-+ } else
-+ vic_chip = &nomadik_vic_priority_chip;
-+ spin_lock_irqsave(&vic_lock, flags);
-+ desc->chip = vic_chip;
-+ spin_unlock_irqrestore(&vic_lock, flags);
+
-+ nmdk_info("Configured PL%2d for irq%d", priority_level, irq);
-+ return (0);
-+}
++ /* Invalidate I cache and Dcache */
++ mov r0,#0
++ mcr p15,0,r0,c7,c7,0
+
-+static void nomadik_vic_configure(unsigned int irq)
-+{
-+ u32 mask = 1UL<<irq%32;
++ /*Drain Write Buffers*/
++ mov r0,#0
++ mcr p15,0,r0,c7,c10,4
+
-+ nmdk_dbg("%s for irq %d", __FUNCTION__, irq);
-+ /* Select interrupt line as Irq (no FIQ used currently)*/
-+ p_vic_register->bank[irq/32].isel &= ~mask;
-+}
++ mov r0,#0
++ mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs
+
-+void __init nomadik_vic_init(void)
-+{
-+ unsigned int i;
++ mov r0,#0
++ mov r0,#0
++ mov r0,#0
++ mov r0,#0
+
-+ nmdk_dbg_ftrace();
-+ /*force default isr value to zero*/
-+ p_vic_register->isr_dvar = (u32)NULL;
-+ for (i = 0; i < MAX_CHIP_IRQ; i++) {
-+ if (1ULL<<i & IRQ_CONF) {
-+ nomadik_vic_configure(i);
-+ set_irq_chip(i, &nomadik_vic_chip);
-+ set_irq_handler(i, handle_level_irq);
-+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-+ }
-+ if (i < VIC_VECTORED_IRQ_NUM) {
-+ /*Disable all vectored interrupts */
-+ p_vic_register->vcr[i] = (u32)NULL;
-+ p_vic_register->var[i] = (u32)NULL;
-+ }
-+ }
-+ nmdk_info("Module initialized Ver("VIC_VER")");
-+}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik ../new/linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik
---- linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik 2008-07-17 16:42:38.000000000 +0530
-@@ -0,0 +1,267 @@
-+if ARCH_NOMADIK
+
-+# The GPIO_PIN_23 is shared between MMC and MSP0.
-+# by default this pin is used for MMC for NOMADIK_NDK15_REV2_B_03 target
-+# to use this pin for MSP it should be configured 'n'
-+config NOMADIK_NDK15_REV2_MMC
-+ bool
-+ default y if NOMADIK_NDK15_REV2_B_03
++#ifdef DEEP_SLEEP_DEBUG
++ ldr r0, =uart1_base
++ ldr r0, [r0,#0x0]
++ mov r1, #0x65
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++ mov r1, #0x66
++ str r1, [r0]
++#endif
+
-+config NOMADIK_NDK10_CUTA
-+ bool
-+ default y if NOMADIK_NDK10_CUT_A1
+
-+config NOMADIK_NDK10_CUTB
-+ bool
-+ default y if (NOMADIK_NDK10_CUT_B0 || NOMADIK_NDK10_CUT_B06)
++/*Try to go back also...FIQ Disabled...IRQ Disabled*/
++ ldmfd sp!,{r0-r12,pc}
+
-+config NOMADIK_GPIO
-+ bool
-+ default y
+
-+config NOMADIK_ENABLE_L2CACHE
-+ bool "Enable L2 Cache controller"
-+ depends on (NOMADIK_NDK15 || NOMADIK_NHK15)
-+ default y if NOMADIK_STN8815CAS22H11
-+ select L2CACHE_ENABLE
-+ help
-+ Nomadik Chip version for this platfrom supports L2 Cache
-+ by default it is enabled, if you want to check system
-+ performanence without L2 Cache, then say no here
++uart1_phys:
++ .word 0x101FB000
++src_phys:
++ .word 0x101E0000
++backup_ram_store_phys:
++ .word 0x80010250
++mtu0_base:
++ .word 0xf01E2000
+
-+config GPIO_PROC
-+ bool
-+ default y
-+ depends on NOMADIK_GPIO
++uart1_base:
++ .word 0xf01FB000
++src_base:
++ .word 0xf01E0000
++pmu_base:
++ .word 0xf01E9000
++fsmc_base:
++ .word 0xf0100000
++backup_ram_base_phys:
++ .word 0x80010000
++vic_base:
++ .word 0xf0140000
++mpmc_base:
++ .word 0xf0110000
++backup_ram_store:
++ .word 0x80010250
++backup_ram_base:
++ .word 0x80010000
++.end
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/dfs.S
+@@ -0,0 +1,355 @@
++/*
++ * arch/arm/mach-nomadik/sleep.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Low-level Nomadik DFS support
++ */
+
-+config NOMADIK_DMA
-+ tristate "NOMADIK DMA SUPPORT"
-+ depends on ISA_DMA_API
-+ default y
-+ help
-+ Nomadik DMA low level driver for standrd DMA interface
++.align 5
++.globl dfs
+
-+config NOMADIK_SSP
-+ tristate "NOMADIK SSP SUPPORT"
-+ depends on (NOMADIK_DMA && NOMADIK_SPI)
-+ default m
-+ help
-+ Depends on Nomadik DMA driver and SPI driver
+
-+config NOMADIK_MSP
-+ tristate "NOMADIK MSP SUPPORT"
-+ depends on (NOMADIK_DMA && NOMADIK_SPI)
-+ default m
-+ help
-+ Depends on Nomadik DMA driver and SPI driver
-+
-+config NOMADIK_MTU
-+ tristate "NOMADIK MTU SUPPORT"
-+ default m
-+ help
-+ The driver offers 8 MTU units tobe used.
-+ In case of module only MTU1 unit will be
-+ available with 4 timers:
-+ MTU1_T0, MTU1_T1, MTU1_T2 & MTU1_T3
-+
-+config NOMADIK_MTU_SYSTEM_TICK
-+ bool "NOMADIK MTU SYSTEM TICK SUPPORT"
-+ depends on NOMADIK_MTU
-+ help
-+ This will prevent the system tick to be used through MTU.
-+ default y
++dfs:
++ stmfd sp!,{r4-r12,lr}
+
-+config NOMADIK_RTC
-+ bool "NOMADIK RTC/RTT SUPPORT"
-+ default y
-+ help
-+ The driver offers RTC and RTT support.
-+ The RTC can be used through /dev/rtc interface for real
-+ time calculations, alarms, long delays if required
-+ If unsure say Y here.
++ str r3, bkup_adr_base
++ add r4, r3, #8
++ str r4, bkup_adr
++ add r4, r3, #0x1c8
++ str r4, bkup_data
++ add r4, r3, #0x388
++ str r4, bkup_action
++ add r4, r3, #0x3f8
++ str r4, bkup_size
+
-+config NOMADIK_PM
-+ bool "NOMADIK POWER MANAGEMENT SUPPORT"
-+ depends on ( (NOMADIK_NHK15 || NOMADIK_NDK15) && NOMADIK_RTC )
-+ default y
-+ select PM if NOMADIK_PM
-+ help
-+ Nomadik Power Management Driver
++ ldr r9, bkup_size
++ ldr r9,[r9]
++ ldr r10,bkup_adr
++ ldr r11,bkup_data
++ ldr r12,bkup_action
+
-+config NOMADIK_SVA_INIT_MEM
-+ bool "NOMADIK SVA MEMORY at initialisation"
-+ default n
-+ help
-+ The driver uses physically contiguous memory allocated
-+ at kernel initialisation time.
-+ If unsure say N here.
++ mrc p15, 0, r3, c10, c0, 0 /* read the lockdown register */
++ orr r3, r3, #1 /* set the preserved bit */
++ mcr p15, 0, r3, c10, c0, 0 /* write to the lockdown register */
+
-+config FORCE_MAX_ZONEORDER
-+ int "Maximum zone order"
-+ default "13"
-+ help
-+ For use cases having large memory requirements choosing a
-+ larger memory size is advised.
+
-+config NOMADIK_SVA_MEM_SIZE
-+ int "SVA initial memory size" if NOMADIK_SVA_INIT_MEM
-+ default "4"
-+ help
-+ For use cases having large memory requirements choosing a
-+ larger memory size is advised.
+
-+config NOMADIK_SVA_VPIP
-+ bool "NOMADIK SVA VPIP support"
-+ default y
-+ help
-+ This enables the support for VPIP in SVA driver. This allows to
-+ create IRP services in SVA to grab the images from sensor CCP0.
-+ Warning: This disables Ethernet & MTD devices.
-+
-+config NOMADIK_SAA_INIT_MEM
-+ bool "NOMADIK SAA MEMORY at initialisation"
-+ default n
-+ help
-+ The SAA driver uses physically contiguous memory allocated
-+ at kernel initialisation time.
-+ If unsure say N here.
+
-+#Configuration for default display setup
-+choice
-+ prompt "Default Display Type"
-+ depends on FB
-+ default FB_NOMADIK_QVGA_PORTRAIT
++ ldr r4, mpmc_base
++ mcr p15, 0, r4, c8, c7, 1
++ ldr r4, [r4]
++ mrc p15, 0, r3, c10, c0, 0
+
-+config FB_NOMADIK_VGA
-+ bool "CLCD VGA"
+
-+config FB_NOMADIK_CRT
-+ bool "CRT VGA"
++ ldr r4, src_base
++ mcr p15, 0, r4, c8, c7, 1
++ ldr r4, [r4]
++ mrc p15, 0, r3, c10, c0, 0
+
-+config FB_NOMADIK_QVGA_PORTRAIT
-+ bool "CLCD QVGA Portrait"
++ ldr r4, bkup_adr_base
++ mcr p15, 0, r4, c8, c7, 1
++ ldr r4, [r4]
++ mrc p15, 0, r3, c10, c0, 0
+
-+config FB_NOMADIK_QVGA_LANDSCAPE
-+ bool "CLCD QVGA Landscape"
+
-+config FB_NOMADIK_WVGA
-+ bool "CLCD WVGA"
-+endchoice
++ bic r3, r3, #1 /* clear preserve bit */
++ mcr p15, 0, r3, c10, c0, 0 /* write to the lockdown register */
+
-+choice
-+ prompt "Default Display BPP"
-+ depends on FB
-+ default FB_NOMADIK_PANEL_24BPP_PACKED
++ ldr r7,mpmc_base
++ ldr r8,src_base
+
-+config FB_NOMADIK_PANEL_8BPP
-+ bool "8 BPP"
++/*
++ mov r7, #0xf0
++ lsl r7, #8
++ orr r7, r7, #0x11
++ lsl r7, #16
+
-+config FB_NOMADIK_PANEL_16BPP
-+ bool "16 BPP"
++ mov r8, #0xf0
++ lsl r8, #8
++ orr r8, r8, #0x1e
++ lsl r8, #16
++*/
+
-+config FB_NOMADIK_PANEL_24BPP
-+ bool "24 BPP"
+
-+config FB_NOMADIK_PANEL_24BPP_PACKED
-+ bool "24 BPP Packed"
++ /* Prefetch certain instructions in the cache. */
++ adr r4, cache_prefetch_start1
++ adr r5, cache_prefetch_end1
++ mvn r3,#0x1F
++ ands r4,r3,r4
++fetch_loop:
++ mcr p15, 0, r4, c7, c13,1
++ cmp r4,r5
++ addls r4, r4, #0x20
++ bls fetch_loop
+
-+endchoice
++mov r0,r0
++mov r0,r0
++mov r0,r0
++mov r0,r0
+
-+config FB_NOMADIK_ACCLN
-+ bool "Nomadik Graphics Acceleration"
-+ tristate
-+ depends on FB
-+ default y
-+ help
-+ enable hw accln for graphics on nomadik
+
-+config FB_NOMADIK_PANEL_BPP
-+ int
-+ default 16 if !FB
-+ default 8 if FB_NOMADIK_PANEL_8BPP
-+ default 16 if FB_NOMADIK_PANEL_16BPP
-+ default 24 if FB_NOMADIK_PANEL_24BPP_PACKED
-+ default 32 if FB_NOMADIK_PANEL_24BPP
++cache_prefetch_start1:
+
-+config FB_NOMADIK_PANEL_NAME
-+ string
-+ default "VGA" if !FB
-+ default "VGA" if FB_NOMADIK_VGA
-+ default "CRT" if FB_NOMADIK_CRT
-+ default "QVGA_Portrait" if FB_NOMADIK_QVGA_PORTRAIT
-+ default "QVGA_Landscape" if FB_NOMADIK_QVGA_LANDSCAPE
-+ default "WVGA" if FB_NOMADIK_WVGA
++ /**
++ *Put SDRAM in self-refresh mode
++ */
++ ldr r3,[r7, #0x20]
++ orr r3,r3,#0x04
++ str r3,[r7, #0x20]
+
-+config FB_NOMADIK_PANEL_XRES
-+ int
-+ default 800 if FB_NOMADIK_WVGA
-+ default 640 if !FB
-+ default 640 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT)
-+ default 240 if FB_NOMADIK_QVGA_PORTRAIT
-+ default 320 if FB_NOMADIK_QVGA_LANDSCAPE
+
-+config FB_NOMADIK_PANEL_YRES
-+ int
-+ default 480 if !FB
-+ default 480 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT || FB_NOMADIK_WVGA)
-+ default 320 if FB_NOMADIK_QVGA_PORTRAIT
-+ default 240 if FB_NOMADIK_QVGA_LANDSCAPE
++ /**
++ *Wait for SDRAM to go in self-refresh
++ */
++wait_till_selfrefresh :
++ ldr r3,[r7,#0x4]
++ and r3,r3,#0x4
++ cmp r3,#0x0
++ beq wait_till_selfrefresh
+
-+config FB_NOMADIK_PANEL_LFMARGIN
-+ hex
-+ default 0xD6 if FB_NOMADIK_WVGA
-+ default 0x21 if !FB
-+ default 0x21 if FB_NOMADIK_VGA
-+ default 0x29 if FB_NOMADIK_CRT
-+ default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
+
-+config FB_NOMADIK_PANEL_RTMARGIN
-+ hex
-+ default 0x27 if FB_NOMADIK_WVGA
-+ default 0x40 if !FB
-+ default 0x40 if FB_NOMADIK_VGA
-+ default 0x09 if FB_NOMADIK_CRT
-+ default 0x2f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++ /**
++ * Stop the DLL, leave SDMC on
++ */
++ ldr r3,[r7]
++ bic r3,r3,#0x2
++ str r3,[r7]
+
-+config FB_NOMADIK_PANEL_UPRMARGIN
-+ hex
-+ default 0x22 if FB_NOMADIK_WVGA
-+ default 0x07 if !FB
-+ default 0x07 if FB_NOMADIK_VGA
-+ default 0x19 if FB_NOMADIK_CRT
-+ default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++ /**
++ *Move the system in Slow mode
++ */
++ ldr r3,[r8]
++ bic r3,r3,#0x7
++ orr r3,r3,#0x2
++ str r3,[r8]
+
-+config FB_NOMADIK_PANEL_LWRMARGIN
-+ hex
-+ default 0xA if FB_NOMADIK_WVGA
-+ default 0x24 if !FB
-+ default 0x24 if FB_NOMADIK_VGA
-+ default 0x02 if FB_NOMADIK_CRT
-+ default 0x0f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++wait_till_slow_mode:
++ ldr r3,[r8]
++ and r3,r3,#0x78
++ cmp r3,#0x10
++ bne wait_till_slow_mode
+
-+config FB_NOMADIK_PANEL_HSLEN
-+ hex
-+ default 0x1 if FB_NOMADIK_WVGA
-+ default 0x40 if !FB
-+ default 0x40 if FB_NOMADIK_VGA
-+ default 0x61 if FB_NOMADIK_CRT
-+ default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++ ldr r3,[r8]
++ bic r3,r3,#0x6000
++ orr r3,r3,r2,LSL #13
++ str r3,[r8]
+
-+config FB_NOMADIK_PANEL_VSLEN
-+ hex
-+ default 0x1 if FB_NOMADIK_WVGA
-+ default 0x19 if !FB
-+ default 0x19 if FB_NOMADIK_VGA
-+ default 0x02 if FB_NOMADIK_CRT
-+ default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++ ldr r3,[r8,#0x14]
++ bic r3,r3,#0x3F00
++ bic r3,r3,#0x7
++ orr r3,r3,r0
++ orr r3,r3,r1,LSL #8
++ str r3,[r8,#0x14]
+
-+config FB_NOMADIK_PANEL_TIM2VAL
-+ hex
-+ default 0x031f1822 if FB_NOMADIK_WVGA
-+ default 0x027f1800 if !FB
-+ default 0x027f1800 if (FB_NOMADIK_VGA)
-+ default 0x027f3800 if (FB_NOMADIK_CRT)
-+ default 0x00ef1804 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
-+#Configuration for default display setup ends here
++ /**
++ *Move the system in Normal mode
++ */
++ ldr r0,[r8, #0x0]
++ ldr r1, =0xfffffff8
++ and r0,r0,r1
++ orr r0,r0,#0x4
++ str r0,[r8, #0x0]
+
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/l2cc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/l2cc.c
---- linux-2.6.20/arch/arm/mach-nomadik/l2cc.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/l2cc.c 2008-07-04 23:45:55.000000000 +0530
-@@ -0,0 +1,152 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/stn8815_devices.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2, as
-+ * published by the Free Software Foundation.
-+ *
-+ * SOC specifc drivers whcih are used as amba devices
-+ */
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/smp.h>
-+#include <linux/amba/bus.h>
-+#include <linux/amba/kmi.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/spi/spi.h>
-+#include <linux/delay.h>
-+#include <linux/amba/clcd.h>
++wait_till_normal_mode:
++ ldr r0,[r8, #0x0]
++ and r0,r0,#0x78
++ cmp r0, #0x20
++ bne wait_till_normal_mode
+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/dma.h>
-+#include <asm/setup.h>
-+#include <asm/param.h>
-+#include <asm/system.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/flash.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/time.h>
-+#include <asm/arch/timex.h>
-+#include <asm/arch/debug.h>
+
++#define ACTION_WRITE 0x01
++#define ACTION_WRITE_AND 0x02
++#define ACTION_WRITE_OR 0x03
++#define ACTION_READ 0x04
++#define ACTION_POLL 0x05
++#define ACTION_POLL_AND 0x06
++#define ACTION_POLL_OR 0x07
++#define ACTION_WAIT 0x08
+
-+#define L210_CACHE_SYNC 0x730
-+#define L210_INV_LINE_PA 0x770
-+#define L210_INV_WAY 0x77C
-+#define L210_CLEAN_LINE_PA 0x7B0
-+#define L210_CLEAN_LINE_IDX 0x7B8
-+#define L210_CLEAN_WAY 0x7BC
-+#define L210_CLEAN_INV_LINE_PA 0x7F0
-+#define L210_CLEAN_INV_LINE_IDX 0x7F8
-+#define L210_CLEAN_INV_WAY 0x7FC
++/*
++ ldr r12,bkup_size
++ ldr r9,[r12]
+
-+static void __iomem *l210_base = (void __iomem *)IO_ADDRESS(NOMADIK_L2CC_BASE);
-+static unsigned long way_size = 0x4000;
++ ldr r10,bkup_adr
++ ldr r11,bkup_data
++ ldr r12,bkup_action
++*/
+
-+static inline void sync_writel(unsigned long val, unsigned long reg,
-+ unsigned long complete_mask)
-+{
-+ writel(val, l210_base + reg);
-+ /* wait for the operation to complete not required for l210 controller */
-+ //while (readl(l210_base + reg) & complete_mask);
-+}
+
-+static inline void cache_sync(void)
-+{
-+ sync_writel(0, L210_CACHE_SYNC, 1);
-+}
++ mov r8,#0x0
++loop1:
++ cmp r8,r9
++ beq end1
+
-+static inline void cacheline_index_op(unsigned long addr, unsigned long reg)
-+{
-+ unsigned long way, index;
++ ldr r7,[r10]
++ ldr r6,[r11]
++ ldr r5,[r12]
+
-+ for (way = 0; way < 8; way++)
-+ for (index = 0; index < way_size; index += PAGE_SIZE) {
-+ unsigned long val = (way << 29) | index | (addr & (PAGE_SIZE - 1));
-+ sync_writel(val, reg, 1);
-+ }
-+}
++ mov r2,r8
++ and r2,r2,#0x3
++ mov r2,r2,LSL #0x3
++ mov r5,r5,LSR r2
++ and r5,r5,#0xFF
+
-+inline void l210_inv_all(void)
-+{
-+ /* invalidate all ways */
-+ sync_writel(0xff, L210_INV_WAY, 0xff);
-+ cache_sync();
-+}
-+EXPORT_SYMBOL(l210_inv_all);
+
-+inline void l210_clean_all(void)
-+{
-+ /* clean all ways */
-+ sync_writel(0xff, L210_CLEAN_WAY, 0xff);
-+ cache_sync();
-+}
-+EXPORT_SYMBOL(l210_clean_all);
++ /**
++ Decide action to be taken
++ */
++ ldr r4,=ACTION_WRITE
++ cmp r5,r4
++ beq action_write
++ ldr r4,=ACTION_WRITE_AND
++ cmp r5,r4
++ beq action_write_and
++ ldr r4,=ACTION_WRITE_OR
++ cmp r5,r4
++ beq action_write_or
++ ldr r4,=ACTION_READ
++ cmp r5,r4
++ beq action_read
++ ldr r4,=ACTION_POLL
++ cmp r5,r4
++ beq action_poll
++ ldr r4,=ACTION_POLL_AND
++ cmp r5,r4
++ beq action_poll_and
++ ldr r4,=ACTION_POLL_OR
++ cmp r5,r4
++ beq action_poll_or
++ ldr r4,=ACTION_WAIT
++ cmp r5,r4
++ beq action_wait
++ b action_end
++action_write:
++#if 0
++ mov r4, #0xf0
++ lsl r4, #8
++ orr r4, #0x1f
++ lsl r4, #8
++ orr r4, #0xb0
++ lsl r4, #8
+
-+inline void l210_flush_all(void)
-+{
-+ /* clean and invalidate all ways */
-+ sync_writel(0xff, L210_CLEAN_INV_WAY, 0xff);
-+ cache_sync();
-+}
-+EXPORT_SYMBOL(l210_flush_all);
++ mov r3, #0x73
++ str r3, [r4]
++#endif
++ str r6,[r7]
++ b action_end
++action_write_and:
+
-+void l210_inv_range(unsigned long start, unsigned long end)
-+{
-+ l210_inv_all();
-+}
-+EXPORT_SYMBOL(l210_inv_range);
++ b action_end
++action_write_or:
++ ldr r3,[r7]
++ orr r3,r3,r6
++ str r3,[r7]
++ b action_end
++action_read:
++ ldr r3,[r7]
++ b action_end
++action_poll:
++ b action_end
++action_poll_and:
++ b action_end
++action_poll_or:
++ b action_end
++action_wait:
++ cmp r6,#0x0
++ beq action_end
++ sub r6,r6,#0x1
++ b action_wait
++action_end:
+
-+void l210_clean_range(unsigned long start, unsigned long end)
-+{
-+ unsigned long size = end - start;
-+ unsigned long addr;
++ add r10,r10,#0x4
++ add r11,r11,#0x4
++ /**
++ * Determine if r8 is multiple of 4 and r12 must be increased
++ */
++ mov r2,r8
++ and r2,r2,#0x3
++ cmp r2,#0x3
++ bne incr8
++ add r12,r12,#0x4
++incr8:
++ add r8,r8,#0x01
++ b loop1
++end1:
+
-+ if (size >= PAGE_SIZE) {
-+ l210_clean_all();
-+ return;
-+ }
++ mov r10, #0xf0
++ lsl r10, #8
++ orr r10, r10, #0x11
++ lsl r10, #16
+
-+ /* no physical address information, flush by index/way */
-+ for (addr = start & ~(32 - 1); addr < end; addr += 32)
-+ cacheline_index_op(addr, L210_CLEAN_LINE_IDX);
-+ cache_sync();
-+}
-+EXPORT_SYMBOL(l210_clean_range);
+
+
-+void l210_flush_range(unsigned long start, unsigned long end)
-+{
-+ unsigned long addr,way,val;
+
-+ //printk("\nl2 flushing hit\n");
-+ /* no physical address information, flush by index/way */
-+ for (addr = start & ~(32 - 1); addr < end; addr += 32)
-+ cacheline_index_op(addr, L210_CLEAN_INV_LINE_IDX);
++ ldr r1,[r10]
++ orr r1,r1,#0x2
++ str r1,[r10]
+
-+ /*for (addr = start; addr < end; addr += 32) {
-+ for (way = 0; way < 8; way++) {
-+ //val = (way << 29) | ((addr & 0x1ff) << 5);
-+ val = (way << 29) | (addr << 5);
-+ sync_writel(val, L220_CLEAN_INV_LINE_IDX, 1);
-+ }
-+ }*/
-+ cache_sync();
-+}
-+EXPORT_SYMBOL(l210_flush_range);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Makefile ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile
---- linux-2.6.20/arch/arm/mach-nomadik/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile 2008-07-04 23:45:06.000000000 +0530
-@@ -0,0 +1,166 @@
-+#
-+# Makefile for the linux kernel.
-+#
++ /* Wait for the DLL to lock */
++waitlock:
++ ldr r1,[r10,#0x4]
++ and r1,r1,#0x8
++ cmp r1,#0x0
++ beq waitlock
+
-+ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
-+include $(TOPDIR)/.config
-+endif
++ /* Exit DDR-SDRAM from self-refresh mode */
++ ldr r1,[r10, #0x20]
++ bic r1,r1,#0x04
++ str r1,[r10, #0x20]
+
-+# Object file lists.
++ /* Wait for DDR-SDRAM to exit from self-refresh */
++loop_refresh:
++ ldr r1,[r10,#0x4]
++ and r1,r1,#0x4
++ cmp r1,#0x4
++ beq loop_refresh
+
-+TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
-+SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
-+PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
-+NMDK_EXTRA_CFLAGS = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
+
-+EXTRA_CFLAGS-y := $(NMDK_EXTRA_CFLAGS)
-+EXTRA_CFLAGS-$(CONFIG_NOMADIK_MTU) += -DCONFIG_MTU0
-+CFLAGS += $(EXTRA_CFLAGS-y)
++ ldmfd sp!,{r4-r12,pc}
+
-+# NMDKDBG_FLAGS maintainence for all Nomadik debuging strategy
-+# Add new entry for new component to be supported here
-+NMDKDBG_FLAGS :=
++mov r0,r0
++mov r0,r0
++mov r0,r0
++mov r0,r0
+
-+ifdef VIC_DEBUG
-+NMDKDBG_FLAGS += -DVIC_DEBUG=$(VIC_DEBUG)
-+endif
++cache_prefetch_end1 : /* This is the end of the code to be copied into eSRAM */
++mov r0,r0
++mov r0,r0
++mov r0,r0
++mov r0,r0
+
-+ifdef RTC_DEBUG
-+NMDKDBG_FLAGS += -DRTC_DEBUG=$(RTC_DEBUG)
-+endif
++bkup_adr_base :
++ .word 0x80010000
++bkup_adr :
++ .word 0x80010008
++bkup_data :
++ .word 0x800101C8
++bkup_action :
++ .word 0x80010388
++bkup_size :
++ .word 0x800103F8
++src_base :
++ .word 0xf01E0000
++mpmc_base :
++ .word 0xf0110000
++uart1_base :
++ .word 0xf01fb000
+
-+ifdef GPIO_DEBUG
-+NMDKDBG_FLAGS += -DGPIO_DEBUG=$(GPIO_DEBUG)
-+endif
+
-+ifdef DMA_DEBUG
-+NMDKDBG_FLAGS += -DDMA_DEBUG=$(DMA_DEBUG)
-+endif
+
-+ifdef EPIO_DEBUG
-+NMDKDBG_FLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG)
-+endif
+
-+ifdef SPI_DEBUG
-+NMDKDBG_FLAGS += -DSPI_DEBUG=$(SPI_DEBUG)
-+endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/dma.c
+@@ -0,0 +1,1337 @@
++/*
++ * arch/arm/mach-nomadik/dma.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Nomadik DMA driver to support standard APIs.
++ * the API details can be found at ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
++ *
++ * Author : Prafulla WADASKAR <prafulla.wadaskar@st.com>
++ */
++#define DMA_VER "2.1.0"
+
-+ifdef SSP_DEBUG
-+NMDKDBG_FLAGS += -DSSP_DEBUG=$(SSP_DEBUG)
-+endif
++#include <linux/module.h> /* module functions */
++#include <linux/slab.h>
++#include <linux/mman.h>
++#include <linux/init.h>
++#include <linux/wait.h> /* For wait queues */
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/spinlock.h> /* spinlocks */
++#include <linux/errno.h> /* err nos */
++#include <linux/sched.h> /* wait macros */
++#include <linux/mm.h> /* GFP flags */
++#include <linux/amba/bus.h> /* Amba device register */
++#include <linux/cpufreq.h>
++#include <asm/page.h>
++#include <asm/dma.h>
++#include <asm/fiq.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/system.h> /* for cli etc */
++#include <asm/hardware.h>
++#include <asm/hardware/iomd.h>
++#include <asm/mach/dma.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/defs.h>
++#include <asm/arch/memory.h>
++#include <asm/arch/debug.h>
+
-+ifdef MSP_DEBUG
-+NMDKDBG_FLAGS += -DMSP_DEBUG=$(MSP_DEBUG)
-+endif
++#define DMA_NAME "DMA"
+
-+ifdef KEYPAD_DEBUG
-+NMDKDBG_FLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG)
-+endif
++#ifndef DMA_DEBUG
++#define DMA_DEBUG 0
++#endif
+
-+ifdef TOUCHP_DEBUG
-+NMDKDBG_FLAGS += -DTOUCHP_DEBUG=$(TOUCHP_DEBUG)
-+endif
++#define NMDK_DEBUG DMA_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX DMA_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
+
-+ifdef POWER_DEBUG
-+NMDKDBG_FLAGS += -DPOWER_DEBUG=$(POWER_DEBUG)
-+endif
++/* Macros used to identify standard dma structure elements for Nomadik implimentation*/
++#define dmaconfig_pipeadr(x) ((x)->dma_base)
+
-+ifdef PM_DEBUG
-+NMDKDBG_FLAGS += -DPM_DEBUG=$(PM_DEBUG)
-+endif
++#define dmaconfig_defconfig(x) ((x)->buf.page)
++#define dmaconfig_config(x) ((x)->buf.offset)
++#define dmaconfig_usrconfig(x) ((x)->buf.dma_address)
++#define dmaconfig_mode(x) ((x)->buf.length)
+
-+ifdef CPUFREQ_DEBUG
-+NMDKDBG_FLAGS += -DCPUFREQ_DEBUG=$(CPUFREQ_DEBUG)
-+endif
++#define dmaconfig_srcadr(x) ((x)->cur_sg.dma_address)
++#define dmaconfig_destadr(x) ((x)->cur_sg.length)
+
-+ifdef SLEEP_DEBUG
-+NMDKDBG_FLAGS += -DSLEEP_DEBUG=$(SLEEP_DEBUG)
-+endif
-+
-+ifdef SVA_DEBUG
-+NMDKDBG_FLAGS += -DSVA_DEBUG=$(SVA_DEBUG)
-+endif
-+#export the nomadik debug flags for driver/* build
-+CFLAGS += $(NMDKDBG_FLAGS)
-+
-+obj-y := gpio.o clock.o timer.o irq.o fsmc.o
-+
-+obj-y += $(SOC_NAME)_devices.o
-+obj-y += $(PLATFORM_NAME)_devices.o
-+
-+# Soc Specific modules
-+
-+obj-$(CONFIG_NOMADIK_PM) += sleep.o deep_sleep.o soft_sleep.o normal.o slow.o pm.o
-+
-+ifeq ($(CONFIG_NOMADIK_PM),y)
-+obj-y += power.o
-+endif
-+
-+ifeq ($(CONFIG_L2CACHE_ENABLE),y)
-+obj-y += l2cc.o
-+endif
-+ifeq ($(CONFIG_CPU_FREQ_NOMADIK),y)
-+obj-y += power.o slow.o
-+endif
-+
-+obj-$(CONFIG_CPU_FREQ_NOMADIK) += cpu.o dfs.o
-+obj-$(CONFIG_NOMADIK_DMA) += nmdkmod_DMA.o
-+obj-$(CONFIG_NOMADIK_SSP) += nmdkmod_ssp.o
-+obj-$(CONFIG_NOMADIK_MSP) += nmdkmod_msp.o
-+obj-$(CONFIG_NOMADIK_MTU) += nmdkmod_mtu.o
-+obj-$(CONFIG_NOMADIK_RTC) += nmdkmod_rtc.o
-+
-+nmdkmod_gpio-objs := gpio.o
-+nmdkmod_DMA-objs := dma.o
-+nmdkmod_ssp-objs := ssp.o
-+nmdkmod_msp-objs := msp.o
-+nmdkmod_mtu-objs := mtu.o
-+nmdkmod_rtc-objs := rtc.o
-+
-+# Auto board configuration/dependency resolution
-+#include $(TOPDIR)/.config
-+
-+SOC_HEADER = include/asm-arm/arch-nomadik/soc_devices.h
-+PDEV_HEADER = include/asm-arm/arch-nomadik/board_devices.h
-+
-+$(TOPDIR)/.platform:
-+ $(Q)echo "Generating $@"
-+ $(Q)echo $(CONFIG_NOMADIK_PLATFORM) > $@
-+
-+$(TOPDIR)/.soc:
-+ $(Q)echo "Generating $@"
-+ $(Q)echo $(CONFIG_NOMADIK_SOC) > $@
-+
-+$(TOPDIR)/.target:
-+ $(Q)echo "Generating $@"
-+ $(Q)echo $(CONFIG_NOMADIK_TARGET) > $@
-+
-+$(TOPDIR)/$(PDEV_HEADER):
-+ $(Q)echo "Generating SYMLINK $(PDEV_HEADER) -> $(PLATFORM_NAME)_devices.h"
-+ $(Q)rm -rf $@
-+ $(Q)ln -s $(PLATFORM_NAME)_devices.h $@
-+
-+$(TOPDIR)/$(SOC_HEADER):
-+ $(Q)echo "Generating SYMLINK $(SOC_HEADER) -> $(SOC_NAME)_devices.h"
-+ $(Q)rm -rf $@
-+ $(Q)ln -s $(SOC_NAME)_devices.h $@
-+
-+# machprepare kjhsdk dfsdf
-+machprepare: $(TOPDIR)/.platform $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/$(SOC_HEADER)
-+
-+# machprepare kjhsdk j
-+machclean:
-+ $(Q)rm -rf *mod.o *.mod.c *.o *.ko
-+
-+machmrproper:
-+ $(Q)rm -rf $(TOPDIR)/$(SOC_HEADER) $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/arch/arm/mach-nomadik/Kconfig $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/.platform
-+
-+#This will resolve any machin specific dependency for configuration
-+#This will generate Kconfig file if not present
-+machconfig:
-+ifneq ($(wildcard $(TOPDIR)/arch/arm/mach-nomadik/Kconfig), $(TOPDIR)/arch/arm/mach-nomadik/Kconfig)
-+ @echo "Generating $(TOPDIR)/arch/arm/mach-nomadik/Kconfig"
-+ @./create_kconfig.pl $(TOPDIR)/arch/arm/mach-nomadik
-+endif
-+
-+# end of Auto board configuration/dependency resolution
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot
---- linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,4 @@
-+ zreladdr-y := 0x00008000
-+params_phys-y := 0x00000100
-+initrd_phys-y := 0x00800000
-+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/msp.c ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.c
---- linux-2.6.20/arch/arm/mach-nomadik/msp.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.c 2008-11-19 16:47:02.000000000 +0530
-@@ -0,0 +1,2062 @@
+/*
-+ * Driver for Nomadik STN8810/STN8815 MSP device.
-+ *
-+ * Copyright 2006 STMicroelectronics Pvt. Ltd.
-+ *
-+ * This program is free sofstware; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
++ * Constants used for DMA channel priority processing
+ */
++#define QUEUE_ID 0x80
++#define POLICY_CHECK_END 0xff
++const u8 policy_mem2mem[10] ={15,14,13,12,
++ QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
++ POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_undefined[34] ={11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,
++ QUEUE_ID+11,QUEUE_ID+10,QUEUE_ID+9,QUEUE_ID+8,
++ QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
++ QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
++ QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
++ POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_high[34] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
++ QUEUE_ID+0,QUEUE_ID+1,QUEUE_ID+2,QUEUE_ID+3,
++ QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
++ QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
++ QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
++ POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_normal[34] ={4,5,6,7,8,9,10,11,3,2,1,0,12,13,14,15,
++ QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
++ QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
++ QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
++ QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
++ POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_low[34] ={8,9,10,11,7,6,5,4,3,2,1,0,12,13,14,15,
++ QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
++ QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
++ QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
++ QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
++ POLICY_CHECK_END, POLICY_CHECK_END};
+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+#include <linux/wait.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/amba/bus.h>
-+#include <linux/delay.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/delay.h>
-+#include <asm/irq.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/defs.h>
-+#include <asm/arch/debug.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/arch/gpio.h>
-+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+#include <asm/arch/spi.h>
-+#include <asm/arch/msp-spi.h>
-+#endif
-+
-+#include <asm/arch/msp.h>
-+
-+#include "msp.h"
-+
-+#ifndef MSP_DEBUG
-+#define MSP_DEBUG 0
-+#endif
-+
-+#define NMDK_MSP_NAME "NOMADIK_MSP"
-+
-+#define NMDK_DEBUG MSP_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX NMDK_MSP_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
-+
-+char MSP_NAME[] = "msp";
-+
-+static volatile struct msp_register *registers[MSP_COUNT] = {
-+ (struct msp_register *)IO_ADDRESS(NOMADIK_MSP0_BASE),
-+#if MSP_COUNT > 1
-+ (struct msp_register *)IO_ADDRESS(NOMADIK_MSP1_BASE),
-+#endif
-+#if MSP_COUNT > 2
-+ (struct msp_register *)IO_ADDRESS(NOMADIK_MSP2_BASE),
-+#endif
-+};
-+
-+static int altfunc[MSP_COUNT] = {
-+ GPIO_ALT_MSP_0,
-+#if MSP_COUNT > 1
-+ GPIO_ALT_MSP_1,
-+#endif
-+#if MSP_COUNT > 2
-+ GPIO_ALT_MSP_2,
-+#endif
-+};
-+static int msp_irq = IRQ_MSP0;
-+
-+static wait_queue_head_t wait[MSP_COUNT];
-+static volatile int msp_io_error[MSP_COUNT];
+
-+static struct msp_context msp_context[MSP_COUNT];
++static char dmach_name[MAX_DMA_CHANNELS * MAX_DMA_CHNAME_SIZE];
++static struct dma_soc_data *socdat;
++static struct dmach_lli *p_lli_pipe[MAX_DMA_HWCHANNELS];
++struct dmach_lli *lli_ptr_log = NULL;
++struct dmach_lli *lli_ptr_phy = NULL;
++#define nomadik_dma_lli_phy_to_logical(x) ((struct dmach_lli *)((u32)(x + (lli_ptr_log - lli_ptr_phy)) & ~0x01))
+
-+static struct msp_mode_status tx_status[MSP_COUNT];
-+static struct msp_mode_status rx_status[MSP_COUNT];
++#define nomadik_dmach_is_active_n_enabled(x) (x & 0x00020001)
++#define nomadik_dma_is_pipe_busy(pipe) (p_lli_pipe[pipe])
++#define nomadik_dma_mark_pipe_busy(pipe) (p_lli_pipe[pipe] = (void *)0xffffffff)
+
-+static u32 input_clock[MSP_COUNT];
-+static u32 spi_clock_mode[MSP_COUNT];
-+static u32 spi_burst_mode[MSP_COUNT];
++/**
++ * nomadik_dma_channel_of_pipe - To get dma channel irq for provided pipe address
++ * @pipeadr: pipe address w.r.to which channel irq needs for foundout
++ *
++ * finds the pipe number assoicated with channel
++ * if any transfer is already scheduled on a pipe, returns the channel irq of scheduled DMA
++ * if pipe is free, returns null
++ */
++static int nomadik_dma_channel_of_pipe(struct dmach_register *pipeadr)
++{
++ u32 pipe;
++ struct dma_struct * dma;
+
-+/*Usage Flag for MSPs*/
-+msp_flag *flag_msp0, *flag_msp1, *flag_msp2;
++ pipe= (((u32)pipeadr & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
++ if ((u32 *)pipeadr > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
++ if (p_lli_pipe[pipe]) {
++ if (p_lli_pipe[pipe]->mem2.dma) {
++ dma = p_lli_pipe[pipe]->mem2.dma;
++ return dma->dma_irq;
++ } else return 0;
++ }
++ return 0;
++}
+
-+static const struct msp_protocol_desc protocol_desc_tab[] = /* Protocol desciptors */
++/**
++ * nomadik_dma_allocate_llis - Allocates requested number of LLIs
++ * @count: No of LLI buffers requested
++ *
++ * reserves the requested number of llis from internal lli poolf
++ * link them with DMAble LLI addresses so that can be used directly by DMA h/w
++ * return the point of first lli
++ */
++static struct dmach_lli *nomadik_dma_allocate_llis(u32 count)
+{
-+ I2S_PROTOCOL_DESC,
-+ /* PCM_PROTOCOL_DESC */
-+ {
-+ MSP_SINGLE_PHASE,
-+ MSP_FRAME_LENGTH_1,
-+ MSP_FRAME_LENGTH_1,
-+ MSP_ELEM_LENGTH_16,
-+ MSP_ELEM_LENGTH_16,
-+ /*below three settings are platform specific */
-+ MSP_DATA_DELAY,
-+ MSP_TX_CLOCK_EDGE,
-+ MSP_RX_CLOCK_EDGE},
-+ PCM_COMPAND_PROTOCOL_DESC,
-+ AC97_PROTOCOL_DESC,
-+ SPI_MASTER_PROTOCOL_DESC,
-+ SPI_SLAVE_PROTOCOL_DESC
-+};
-+/* local functions */
-+static irqreturn_t handle_irq(int irq, void *dev_id);
-+static int transmit_data(int msp, void *data, size_t bytes);
-+static int receive_data(int msp, void *data, size_t bytes);
-+static int transmit_receive_data(int msp, int work_mode,
-+ void *txdata, size_t txbytes, void *rxdata,
-+ size_t rxbytes);
-+static int configure_clock(int msp, int protocol, u32 input_clock,
-+ u32 frame_freq, int frame_size);
-+static int configure_protocol(int msp, int protocol, int direction,
-+ enum msp_data_size data_size);
++ struct dmach_lli *p_lli = lli_ptr_log;
++ struct dmach_lli *p_lli_phy = lli_ptr_phy;
++ struct dmach_lli *p_lli_phylast = (struct dmach_lli *)0x01;
++ unsigned long flags;
+
++ nmdk_dbg_ftrace();
++ if (!(p_lli) || !(count)) return (struct dmach_lli *)NULL;
++ if (count > MAX_DMA_LLIS) return (struct dmach_lli *)NULL;
++ flags = claim_dma_lock();
++ do {
++ if (p_lli == (lli_ptr_log + MAX_DMA_LLIS-2)) {
++ nmdk_error("unable to find free lli.. rechecking...");
++ p_lli = lli_ptr_log;
++ p_lli_phy = lli_ptr_phy;
++ }
++ p_lli++; p_lli_phy++;
++ if (!(p_lli->mem3.next)) {
++ p_lli->mem3.next = p_lli_phylast;
++ count--;
++ p_lli_phylast = (struct dmach_lli *)((u32)p_lli_phy + 0x01);
++ }
++ } while (count);
++ release_dma_lock(flags);
++ return p_lli;
++}
+
+/**
-+ * nomadik_msp_configure - configures the MSP controller
-+ * @msp - specifies the msp controller to configure.
-+ * @config - specifies the configuration parameters.
++ * nomadik_dma_deallocate_llis - deallocates/frees the provided lli list
++ * @p_lli: pointer to the first lli
++ *
++ * frees all llis in the provided lli list
+ */
-+int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user)
++static void nomadik_dma_deallocate_llis(struct dmach_lli *p_lli)
+{
-+ u32 old_reg;
-+ u32 new_reg;
-+ u32 mask;
-+ int status = 0;
-+
-+ if (msp < 0 || msp > MSP_COUNT) {
-+ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+ return -EINVAL;
-+ }
-+ nmdk_dbg("In nomadik_msp_configure, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
-+ nmdk_dbg("In nomadik_msp_configure, flag_msp1 is %d\n", flag_msp1->user);
-+ nmdk_dbg("In nomadik_msp_configure, flag_msp2 is %d\n", flag_msp2->user);
++ struct dmach_lli *p_lli_bkup;
+
-+ switch(msp) {
-+ case 0: if((flag_msp0->user != MSP_NO_USER) && (flag_msp0->user != user)){
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP0 already in use in %d mode", flag_msp0->user);
-+ }
-+ else {
-+ down(&flag_msp0->lock);
-+ flag_msp0->user = user;
-+ up(&flag_msp0->lock);
-+ }
-+ break;
-+ case 1: if((flag_msp1->user != MSP_NO_USER) && (flag_msp1->user != user)){
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP1 already in use in %d mode", flag_msp1->user);
-+ }
-+ else {
-+ down(&flag_msp1->lock);
-+ flag_msp1->user = user;
-+ up(&flag_msp1->lock);
-+ }
-+ break;
-+ case 2: if((flag_msp2->user != MSP_NO_USER) && (flag_msp2->user != user)){
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP2 already in use in %d mode", flag_msp2->user);
-+ }
-+ else
-+ down(&flag_msp2->lock);
-+ flag_msp2->user = user;
-+ up(&flag_msp2->lock);
++ nmdk_dbg_ftrace();
++ while (p_lli) {
++ if (!(p_lli)) break;
++ if (!(p_lli->mem3.next)) break;
++ if ((u32)p_lli->mem3.next == 0x01) {
++ p_lli->mem3.next = (struct dmach_lli *)NULL;
+ break;
++ }
++ p_lli_bkup = nomadik_dma_lli_phy_to_logical(p_lli->mem3.next);
++ p_lli->mem3.next = (struct dmach_lli *)NULL;
++ p_lli = p_lli_bkup;
+ }
-+ if(status) {
-+ printk(KERN_ERR "Error in setting flag bit for MSP\n");
-+ return status;
-+ }
-+
-+ /* First do the global config register */
-+ mask =
-+ RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FRAME_SYNC_MASK |
-+ TX_FRAME_SYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
-+ RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK;
-+
-+ new_reg =
-+ (config->tx_clock_sel | config->rx_clock_sel | config->
-+ rx_frame_sync_pol | config->tx_frame_sync_pol | config->
-+ rx_frame_sync_sel | config->tx_frame_sync_sel | config->
-+ rx_fifo_config | config->tx_fifo_config | config->srg_clock_sel);
-+
-+ old_reg = (registers[msp]->global_ctrl);
-+ old_reg &= ~mask;
-+ old_reg |= new_reg;
-+ (registers[msp]->global_ctrl) = old_reg;
-+
-+ /* Now do the tx_config and rx_config registers */
-+ old_reg = registers[msp]->rx_config;
-+ mask = MSP_NON_MODE_BIT_MASK;
-+ new_reg = config->rx_endianess | config->rx_unexpect_frame_sync;
-+ old_reg &= ~mask;
-+ old_reg |= new_reg;
-+ (registers[msp]->rx_config) = old_reg;
-+ old_reg = registers[msp]->tx_config;
-+ new_reg = config->tx_endianess | config->tx_unexpect_frame_sync;
-+ old_reg &= ~mask;
-+ old_reg |= new_reg;
-+ (registers[msp]->tx_config) = old_reg;
-+
-+ /* Set global input clock and spi clock mode, needed by other config ops */
-+
-+ input_clock[msp] = config->input_clock_freq;
-+ spi_clock_mode[msp] = config->spi_clk_mode;
-+ spi_burst_mode[msp] = config->spi_burst_mode;
-+ return 0;
+}
+
+/**
-+ * nomadik_msp_enable - Enable the msp controller with given configuration
-+ * @msp - specifies the msp controller
-+ * @direction - specifies the transmit/receive direction
-+ * @work_mode - specifies DMA/Interrupt/Polling mode
-+ * @protocol - Either PCM/I2S
-+ * @frame_freq - specifies the frequency.
-+ * @frame_size - specifies frame size
-+ * @data_size - specifies element size
++ * nomadik_dma_schedule_xfer_on_pipe - Schedules DMA transfer lli on a pipe
++ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
++ * @p_lli: pointer to the lli to be scheduled
++ *
++ * finds out the pipe no associated with a pipe
++ * checkes whether pipe is free or busy
++ * if free then
++ * Configures the pipe with LLI data
++ * clears any pending interrupt on a pipe
++ * marks pipe as busy
++ * Enables DMA to strat transfer
++ * if pipe is busy then
++ * queues the lli on the pipe
+ */
-+int nomadik_msp_enable(int msp, int direction, int work_mode, int protocol,
-+ int frame_freq, int frame_size,
-+ enum msp_data_size data_size, t_msp_user user)
++static void nomadik_dma_schedule_xfer_on_pipe(volatile struct dmach_register *p_pipe, struct dmach_lli *p_lli)
+{
-+ int status = 0;
-+ int skip_irq;
-+ if (msp < 0 || msp > MSP_COUNT) {
-+ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+ return -EINVAL;
-+ }
-+
-+ nmdk_dbg("In nomadik_msp_enable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
-+ switch(msp) {
-+ case 0: if(flag_msp0->user != user) {
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP0 not usable in Non SPI mode\n");
-+ }
-+ break;
-+ case 1: if(flag_msp1->user != user) {
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP1 not usable in Non SPI mode\n");
-+ }
-+ break;
-+ case 2: if(flag_msp2->user != user) {
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP2 not usable in Non SPI mode\n");
-+ }
-+ break;
-+ }
-+ if(status) {
-+ printk(KERN_ERR "Error in setting flag bit for MSP, status is %d\n", status);
-+ return status;
-+ }
++ u32 pipe, i;
++ struct dmach_lli *p_lli_hw, *p_lli_curr;
++ volatile struct dma_register *p_dma_reg;
+
-+ skip_irq = (registers[msp]->global_ctrl) & (TX_ENABLE | RX_ENABLE);
++ nmdk_dbg_ftrace();
++ i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
++ pipe = i*2;
++ if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
+
-+ if(!skip_irq) {
-+ switch (msp) {
-+ case 0:
-+ status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_0");
-+ break;
-+ case 1:
-+ status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_1");
-+ break;
-+ case 2:
-+ status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_2");
-+ break;
-+ }
-+ if (status) {
-+ printk(KERN_ERR "Error in nomadik_gpio_altfuncenable, status is %d\n", status);
-+ return status;
++ p_lli->mem1.p_lli_qh = (struct dmach_lli *)NULL; /*Marked this lli as last in queue*/
++ p_lli_curr = p_lli_pipe[pipe];
++ mb();
++ if ((p_lli_curr != (void*)0xffffffff) && (p_lli_curr != NULL) ) {
++ while (p_lli_curr->mem1.p_lli_qh) {
++ nmdk_dbg2("currlli(%p) next_lli (%p)", p_lli_curr, p_lli_curr->mem1.p_lli_qh);
++ p_lli_curr = p_lli_curr->mem1.p_lli_qh; /*go thr lli headers to point last lli head */
+ }
++ p_lli_curr->mem1.p_lli_qh = p_lli;
++ nmdk_dbg2("lli(%p) is queued on PIPE %d at %p", p_lli, pipe, p_lli_curr);
++ } else {
++ /* clear any pending interrupt on this pipe if any */
++ p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
++ p_dma_reg->tcicr |= 1UL<<i;
++ p_dma_reg->eicr |= 1UL<<i;
++ nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
++
++ /* program pipe for a transfer*/
++ p_lli_pipe[pipe] = p_lli;
++ p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
++ p_pipe->sadr = p_lli_hw->mem1.sadr;
++ p_pipe->dadr = p_lli_hw->mem2.dadr;
++ p_pipe->lli = p_lli_hw->mem3.next;
++ p_pipe->cr = p_lli_hw->mem4.cr;
++ nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
++ (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
++ mb();
++ p_pipe->cfg = p_lli->mem4.cfg;
+ }
++}
+
-+ /* Store context data for power management */
-+ msp_context[msp].direction = direction;
-+ msp_context[msp].mode = work_mode;
-+ msp_context[msp].protocol = protocol;
-+ msp_context[msp].frame_freq = frame_freq;
-+ msp_context[msp].frame_size = frame_size;
-+ msp_context[msp].requested_data_size = data_size;
++/**
++ * nomadik_dma_free_procesed_pipe - Frees processed LLI on a pipe
++ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
++ *
++ * finds out the pipe no associated with a pipe
++ * checkes whether pipe is free or busy, if free then just returns
++ * frees the allocated llis for a pipe
++ * checks whether any transfer is queued on a pipe
++ * if the queue is not empty then
++ * Configures queues lli as current lli
++ * Configures the pipe with LLI data
++ * clears any pending interrupt on a pipe
++ * marks pipe as busy
++ * Enables DMA to strat transfer
++ * if the queue is empty then
++ * marks the pipe as free if not reserved by requesting DMA Channel
++ * otherwise marks the pipe as free
++ */
++static void nomadik_dma_free_procesed_pipe(volatile struct dmach_register *p_pipe)
++{
++ u32 pipe;
++ struct dmach_lli *p_lli;
++ dma_t *dma;
++ struct dmach_lli *p_lli_hw;
++ volatile struct dma_register *p_dma_reg;
++ u32 i;
+
-+ /* Configure msp with protocol dependent settings */
-+ configure_protocol(msp, protocol, direction, data_size);
++ nmdk_dbg_ftrace();
++ i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
++ pipe = i*2;
++ if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
+
-+ configure_clock(msp, protocol, input_clock[msp], frame_freq,
-+ frame_size);
++ /* free lli of processed pipe*/
++ if ((p_lli_pipe[pipe] != (void *)0xffffffff) && (p_lli_pipe[pipe] != NULL) ) {
++ dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
++ p_lli = p_lli_pipe[pipe]->mem1.p_lli_qh;
++ nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
++ mb();
++ if (p_lli) {
++ /* clear any pending interrupt on this pipe if any */
++ p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
++ /*p_dma_reg->tcicr |= 1UL<<i;*/
++ p_dma_reg->eicr |= 1UL<<i;
++ nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
+
-+ switch (direction) {
-+ case MSP_TRANSMIT_MODE:
-+ registers[msp]->irq_mask |= TRANSMIT_UNDERRUN_ERR_INT;
-+ if (work_mode == MSP_DMA_MODE) {
-+ registers[msp]->dma_ctrl |= TX_DMA_ENABLE;
-+ }
++ /* program pipe for a transfer*/
++ p_lli_pipe[pipe] = p_lli;
++ p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
++ p_pipe->sadr = p_lli_hw->mem1.sadr;
++ p_pipe->dadr = p_lli_hw->mem2.dadr;
++ p_pipe->lli = p_lli_hw->mem3.next;
++ p_pipe->cr = p_lli_hw->mem4.cr;
++ nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
++ (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
++ mb();
++ p_pipe->cfg = p_lli->mem4.cfg;
+
-+ tx_status[msp].work_mode = work_mode;
-+ if (protocol == MSP_I2S_PROTOCOL) {
-+ tx_status[msp].stereo_mode = MSP_STEREO;
++ nmdk_dbg2("Scheduling queued transfer on pipe %d (lli(%p))", pipe,
++ p_lli_pipe[pipe]);
+ } else {
-+ tx_status[msp].stereo_mode = MSP_MONO;
-+ }
-+
-+ (registers[msp]->global_ctrl) &= ~RX_ENABLE;
-+ (registers[msp]->global_ctrl) |= TX_ENABLE;
-+ break;
-+ case MSP_RECEIVE_MODE:
-+ registers[msp]->irq_mask |= RECEIVE_OVERRUN_ERROR_INT;
-+ if (work_mode == MSP_DMA_MODE) {
-+ registers[msp]->dma_ctrl |= RX_DMA_ENABLE;
++ if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
++ p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
++ else {
++ p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
++ dmaconfig_pipeadr(dma) = (u32)0;
++ }
+ }
++ }
++}
+
-+ rx_status[msp].work_mode = work_mode;
-+ if (protocol == MSP_I2S_PROTOCOL) {
-+ rx_status[msp].stereo_mode = MSP_STEREO;
-+ } else {
-+ rx_status[msp].stereo_mode = MSP_MONO;
-+ }
++/* removes all allocated requests on the pipe */
++/**
++ * nomadik_dma_flush_pipe - Removes all scheduled and queued transfers on a pipe
++ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
++ *
++ * finds out the pipe no associated with a pipe
++ * stops current transfer
++ * traverse through lli heads and flush all queued llis including scheduled one
++ * marks the pipe as free
++ */
++static void nomadik_dma_flush_pipe(volatile struct dmach_register *p_pipe)
++{
++ u32 pipe;
++ struct dmach_lli *p_lli_qh = (struct dmach_lli *)NULL;
++ dma_t *dma;
+
-+ (registers[msp]->global_ctrl) |= RX_ENABLE;
-+ (registers[msp]->global_ctrl) &= ~TX_ENABLE;
-+ break;
-+ case MSP_BOTH_T_R_MODE:
-+ registers[msp]->irq_mask |=
-+ TRANSMIT_UNDERRUN_ERR_INT | RECEIVE_OVERRUN_ERROR_INT;
-+ if (work_mode == MSP_DMA_MODE) {
-+ registers[msp]->dma_ctrl |=
-+ TX_DMA_ENABLE | RX_DMA_ENABLE;
-+ }
++ nmdk_dbg_ftrace();
++ pipe= (((u32)p_pipe & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
++ if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
+
-+ tx_status[msp].work_mode = work_mode;
-+ rx_status[msp].work_mode = work_mode;
-+ if (protocol == MSP_I2S_PROTOCOL) {
-+ tx_status[msp].stereo_mode = MSP_STEREO;
-+ rx_status[msp].stereo_mode = MSP_STEREO;
-+ } else {
-+ tx_status[msp].stereo_mode = MSP_MONO;
-+ rx_status[msp].stereo_mode = MSP_MONO;
-+ }
++ if ((u32)p_lli_pipe[pipe] == 0xffffffff) goto nextt;
++ while (p_lli_pipe[pipe] != 0) {
++ dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
++ p_lli_qh = p_lli_pipe[pipe]->mem1.p_lli_qh;
++ nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
++ p_lli_pipe[pipe] = p_lli_qh;
++ nmdk_dbg2("Flushed lli (%p) for pipe %d", p_lli_pipe[pipe], pipe);
++ };
++ nextt:
++// if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
++// p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
++// else
++ p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
++}
+
-+ (registers[msp]->global_ctrl) |= RX_ENABLE;
-+ (registers[msp]->global_ctrl) |= TX_ENABLE;
-+ break;
-+ default:
-+ printk(KERN_ERR "Invalid direction parameter\n");
-+ return -EINVAL;
++/**
++ * nomadik_dma_check_update_userconfig - updates config as per user configs
++ * @dma: DMA channel structure pointer
++ *
++ * checks the user configuration
++ * if some use configuration is provided by clinet driver during
++ * configuration then abstracts it and updates Channel configuration
++ * data accordingly
++ */
++static void nomadik_dma_check_update_userconfig(dma_t *dma)
++{
++ nmdk_dbg_ftrace();
++ if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_BSIZE_CONFIGURED) {
++ dmaconfig_config(dma) &= ~(DMA_BSIZE_256);
++ dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_BSIZE_256);
+ }
-+
-+ /* enable frame generation logic */
-+ (registers[msp]->global_ctrl) |= FRAME_GEN_ENABLE;
-+ msp_context[msp].msp_disable = 0;
-+ if (!skip_irq) {
-+ status = request_irq(msp_irq, handle_irq,
-+ SA_INTERRUPT | SA_SHIRQ, MSP_NAME,
-+ (void *)registers[msp]);
-+ if(status)
-+ printk(KERN_ERR "Error while request_irq, err is %d\n", status);
++ if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_BSIZE_CONFIGURED) {
++ dmaconfig_config(dma) &= ~(DMA_BSIZE_256<<3);
++ dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_BSIZE_256<<3);
+ }
-+ return status;
++ if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_WIDTH_CONFIGURED) {
++ dmaconfig_config(dma) &= ~(DMA_WIDTH_NA);
++ dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_WIDTH_NA);
++ }
++ if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_WIDTH_CONFIGURED) {
++ dmaconfig_config(dma) &= ~(DMA_WIDTH_NA<<3);
++ dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_WIDTH_NA<<3);
++ }
++ nmdk_dbg("usrconfig =%08x, config = %08x", (u32)dmaconfig_usrconfig(dma), (u32)dmaconfig_config(dma));
+}
+
-+void nomadik_msp_flush_input(int msp)
++/**
++ * nomadik_dma_usrdevconfig - updates user configuration as per type
++ * @config: user configuration information
++ * @type: src or destincation peripharal indicator (0= means src)
++ *
++ * checks provided configuration and returns configuration converting
++ * it for soruce or destination peripharal. this API is provided to
++ * facilitate and mistake proffing the configuration by client driver
++ */
++u32 __nomadik_dma_usrdevconfig(u32 config, int type)
+{
-+ u32 dummy;
-+ while (!(registers[msp]->status & RX_FIFO_EMPTY)) {
-+ dummy = registers[msp]->fifo;
++ u32 val =0;
++ if (type == 0) { /*src*/
++ if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
++ val |= DMA_SRC_BSIZE_CONFIGURED;
++ val |= (config & DMA_BSIZE_256);
++ }
++ if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
++ val |= DMA_SRC_WIDTH_CONFIGURED;
++ val |= (config & DMA_WIDTH_NA);
++ }
++ } else { /*dest*/
++ if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
++ val |= DMA_DEST_BSIZE_CONFIGURED;
++ val |= (config & DMA_BSIZE_256)<<3;
++ }
++ if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
++ val |= DMA_DEST_WIDTH_CONFIGURED;
++ val |= (config & DMA_WIDTH_NA)<<3;
++ }
+ }
++ return (val);
+}
++EXPORT_SYMBOL(__nomadik_dma_usrdevconfig);
+
-+int nomadik_msp_send_data(int msp, void *data, size_t bytes)
++/**
++ * nomadik_dmach_configure - configures DMA Channel processing default and user configuration
++ * @srcdmadev: name of srouce DMAble device IP
++ * @destdmadev: name of dest DMAble device IP
++ * @dma: DMA channel data structure pointer
++ *
++ * finds out the defult configuration for src and dest devices scanning the config_tbl
++ * prepares DMA configuration from default config of src and dest dmadevices and user
++ * configuration
++ * return 0 on cusess, negative value on failure
++ */
++static int nomadik_dmach_configure(char *src_dmadev, char *dest_dmadev, dma_t *dma)
+{
-+ int status;
-+
-+ if (msp < 0 || msp > MSP_COUNT) {
-+ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+ return -EINVAL;
-+ }
++ int i;
++ uint8 flag =0;
+
-+ if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
-+ printk(KERN_ERR
-+ "Trying to transmit with transmit not enabled\n");
-+ return -EPERM;
-+ }
++ nmdk_dbg_ftrace();
++ dmaconfig_config(dma) = 0;
+
-+ switch (tx_status[msp].work_mode) {
-+ case MSP_DMA_MODE:
-+ printk(KERN_WARNING "Function not authorized in DMA mode\n");
-+ return -ENOSYS;
-+ break;
-+ case MSP_POLLING_MODE:
-+ case MSP_INTERRUPT_MODE:
-+ status = transmit_data(msp, data, bytes);
-+ break;
-+ default:
-+ printk(KERN_ERR "tx work mode invalid: %d\n",
-+ tx_status[msp].work_mode);
-+ return -EINVAL;
-+ break;
++ for (i=0; i < socdat->config_tbl_size; i++) {
++ if (!(strcmp (src_dmadev, (socdat->config_tbl[i].id)))) {
++ dmaconfig_config(dma) |= (u32) (socdat->config_tbl[i].config &
++ (DMA_AHB_M1 | DMA_DEV_BOTH_DMACS_CANBE_USED | DMA_ADR_INC |
++ DMA_WIDTH_NA | DMA_BSIZE_256 |
++ DMA_REQUEST_LINE(31)));
++ flag |=0x01;
++ }
++ if (!(strcmp(dest_dmadev,(socdat->config_tbl[i].id)))) {
++ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config
++ & DMA_DEV_BOTH_DMACS_CANBE_USED)<<2));
++ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_AHB_M1)<<1));
++ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_ADR_INC)<<1)); /*DI bit*/
++ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_WIDTH_NA)<<3));
++ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_BSIZE_256)<<3));
++ dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_REQUEST_LINE(31))<<5));
++ flag |=0x02;
++ }
++ if ((flag & 0x03) == 0x03) {
++ nomadik_dma_check_update_userconfig(dma);
++ nmdk_dbg("conf(%08x), mode=%08x", dmaconfig_config(dma), dmaconfig_mode(dma));
++ return(0);
++ }
+ }
-+
-+ return status;
++ nmdk_error("unable to configure dmachanel");
++ return(-1);
+}
+
-+int nomadik_msp_receive_data(int msp, void *data, size_t bytes)
++/**
++ * nomadik_dma_find_dmahwpipe - Finds and returns free and compatible DMA pipe
++ * @dma: DMA channel data structure pointer
++ *
++ * searches a free pipe as per channel priority policy manager
++ * (refer ./Documentation//arm/STM-Nomadik/dma_user_guide.txt)
++ * checks the configuration for the pipe suitability for transfer
++ * selects the pipe and mark it as busy
++ * returns pipe address if selected
++ * returns NULL in case of unavailability of pipe
++ */
++static struct dmach_register *nomadik_dma_find_dmahwpipe(dma_t *dma)
+{
-+ int status;
++ int i;
++ u8 *p_pipe;
++ volatile struct dmach_register *p_dmach_reg;
++ volatile struct dma_register *p_dma_reg;
++ unsigned long flags;
+
-+ if (msp < 0 || msp > MSP_COUNT) {
-+ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+ return -EINVAL;
-+ }
++ nmdk_dbg_ftrace();
+
-+ if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
-+ printk(KERN_ERR "Trying to receive with receive not enabled\n");
-+ return -EPERM;
++ flags = claim_dma_lock();
++ /* channel priority setup */
++ if ( MEM_TO_MEM == (u32)dmaconfig_mode(dma)) {
++ p_pipe = (void *)policy_mem2mem;
+ }
-+
-+ switch (rx_status[msp].work_mode) {
-+ case MSP_DMA_MODE:
-+ printk(KERN_WARNING "Function not authorized in DMA mode\n");
-+ return -ENOSYS;
-+ break;
-+ case MSP_POLLING_MODE:
-+ case MSP_INTERRUPT_MODE:
-+ status = receive_data(msp, data, bytes);
-+ break;
-+ default:
-+ printk(KERN_ERR "rx work mode invalid: %d\n",
-+ rx_status[msp].work_mode);
-+ return -EINVAL;
-+ break;
++ else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_HIGH) {
++ p_pipe = (void *)policy_high;
+ }
-+
-+ return status;
++ else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_NORMAL) {
++ p_pipe = (void *)policy_normal;
++ }
++ else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_LOW) {
++ p_pipe = (void *)policy_low;
++ }
++ else { /* DMA_EXCH_PRIORITY_UNDEFINED) */
++ p_pipe = (void *)policy_undefined;
++ }
++ do {
++ i = *p_pipe & ~QUEUE_ID;
++ /** Advanced Pipe selection strategy, under development */
++ /* skip if pipe is busy and not requested on queued pipe */
++ if (nomadik_dma_is_pipe_busy(i) && (!(*p_pipe & QUEUE_ID))) continue;
++ /* skip if pipe is busy with infinite dma xfer */
++ if (nomadik_dma_is_pipe_busy(i) &&
++ ((dmaconfig_config((dma_t *)p_lli_pipe[i]->mem2.dma)) & DMA_INFINITE_XFER)) continue;
++ if (i & 0x01) {
++ if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)))
++ != (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)) ) continue;
++ p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA1].chip_data;
++ } else {
++ if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)))
++ != (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)) ) continue;
++ p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA0].chip_data;
++ }
++ p_dmach_reg = (struct dmach_register *)&p_dma_reg->dmach[i/2];
++ nomadik_dma_mark_pipe_busy(*p_pipe & ~QUEUE_ID);
++ nmdk_dbg("DMAHW PIPE%d assigned for Dma Channel %d",i, DMACH_FOR_IRQNO(dma->dma_irq));
++ release_dma_lock(flags);
++ return (void *)p_dmach_reg;
++ } while ((*(++p_pipe)) != POLICY_CHECK_END);
++ release_dma_lock(flags);
++ nmdk_error("All HW DMA Chanels busy...");
++ return NULL;
+}
+
-+int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
-+ void *rxdata, size_t rxbytes)
++/**
++ * nomadik_dma_req - low level method for request_dma API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Check for configuration is passed by client
++ * prepares basic channel configuration from dma info provided by client
++ * generate dmach id string from src and dest dmadevtypes
++ * find and reserved a pipe in case of reserved mode requested by client
++ * returns NULL in case of sucess, negative value in case for failure
++ */
++static int nomadik_dma_req(dmach_t channel, dma_t *dma)
+{
-+ int status;
++ struct nmdk_dma_info *dma_info =
++ (struct nmdk_dma_info *)dma->device_id;
++ int error;
+
-+ if (msp < 0 || msp > MSP_COUNT) {
-+ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+ return -EINVAL;
-+ }
++ nmdk_dbg_ftrace();
+
-+ if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
-+ printk(KERN_ERR "Trying to receive with receive not enabled\n");
-+ return -EPERM;
++ if (! dma->device_id) {
++ nmdk_error("nmdk_dma_info structptr not passed");
++ return (-DMA_CONFIG_INFO_NOT_PASSED);
+ }
+
-+ if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
-+ printk(KERN_ERR
-+ "Trying to transmit with transmit not enabled\n");
-+ return -EPERM;
-+ }
++ dmaconfig_mode(dma) = (u32)dma_info->mode;
++ dmaconfig_usrconfig(dma) = (u32)dma_info->config;
+
-+ if (tx_status[msp].work_mode != rx_status[msp].work_mode) {
-+ printk(KERN_ERR "Inconsistent transmit/reveive modes\n");
-+ return -EINVAL;
++ /* Prepare dmach configuration form dma_info*/
++ switch((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
++ case MEM_TO_MEM:
++ dma_info->srcdevtype = "mem";
++ dma_info->destdevtype = "mem";
++ break;
++ case FLOW_CNTRL_PERIPH(MEM_TO_PERIPH):
++ case MEM_TO_PERIPH:
++ dma_info->srcdevtype = "mem";
++ break;
++ case FLOW_CNTRL_PERIPH(PERIPH_TO_MEM):
++ case PERIPH_TO_MEM:
++ dma_info->destdevtype = "mem";
++ break;
++ case FLOW_CNTRL_SRC_PERIPH(PERIPH_TO_PERIPH):
++ case FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH):
++ case PERIPH_TO_PERIPH:
++ break;
++ default:
++ nmdk_error("Invalid DMA mode");
++ error =-1;
++ goto err_exit;
+ }
+
-+ switch (tx_status[msp].work_mode) {
-+ case MSP_DMA_MODE:
-+ printk(KERN_WARNING "Function not authorized in DMA mode\n");
-+ return -ENOSYS;
-+ break;
-+ case MSP_POLLING_MODE:
-+ case MSP_INTERRUPT_MODE:
-+ status = transmit_receive_data(msp, tx_status[msp].work_mode,
-+ txdata, txbytes,
-+ rxdata, rxbytes);
-+ break;
-+ default:
-+ printk(KERN_ERR "work mode invalid: %d\n",
-+ tx_status[msp].work_mode);
-+ return -EINVAL;
-+ break;
++ if (! dma_info->srcdevtype) {
++ nmdk_error("srcdevtype not specified");
++ error =-DMA_SRC_DEVICE_NOT_CONFIGURED;
++ goto err_exit;
++ }
++ if (! dma_info->destdevtype) {
++ nmdk_error("destdevtype not specified");
++ error =-DMA_DEST_DEVICE_NOT_CONFIGURED;
++ goto err_exit;
+ }
++ error = nomadik_dmach_configure(dma_info->srcdevtype, dma_info->destdevtype, dma);
++ if (error) goto err_exit;
+
-+ return status;
-+}
++ /* generate dmach id string from src and dest dmadevtypes */
++ sprintf(dmach_name + (channel * MAX_DMA_CHNAME_SIZE ),
++ "dmaclbk-%s->%s", dma_info->srcdevtype, dma_info->destdevtype);
++ dma->device_id = dmach_name + (channel * MAX_DMA_CHNAME_SIZE) + 8;
+
-+static int nomadik_msp_wait_for_tx_complete(int msp)
-+{
-+ while (!(registers[msp]->status & TX_FIFO_EMPTY));
-+ return 0;
++ if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) {
++ dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
++ if ((u32)dmaconfig_pipeadr(dma)) {
++ nmdk_dbg("pipe (%p) reserved for channel %d",
++ (void *)dmaconfig_pipeadr(dma), channel);
++ } else {
++ nmdk_error("could not reserve dmach hw pipe");
++ error =-1;
++ goto err_exit;
++ }
++ } else dmaconfig_pipeadr(dma) = (u32)NULL;
++ dma->state = NMDK_DMA_CONFIGURED;
++ return(0);
++
++ err_exit:
++ return(error);
+}
+
+/**
-+ * nomadik_msp_disable - disable the given msp controller
-+ * @msp - specifies the msp contoller
-+ * @direction - specifies the transmit/receive direction
++ * nomadik_dma_en - low level method for enable_dma API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Checks for channel configured properly
++ * allocates llis for transfer
++ * programm llis for transfer data
++ * checks if the pipe is already available with channel
++ * if not the find and allocates a free pipe for a transfer
++ * program dmach irqname if not set by client
++ * schedules a transfer on a pipe
+ */
-+int nomadik_msp_disable(int msp, int direction, t_msp_user user)
++static void nomadik_dma_en(dmach_t channel, dma_t *dma)
+{
-+ int status = 0;
-+ if (msp < 0 || msp > MSP_COUNT) {
-+ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+ return -EINVAL;
++ struct dmach_lli *p_lli_start = (struct dmach_lli *)NULL;
++ struct dmach_lli *p_lli_curr;
++ struct dmach_lli *p_lli_next;
++
++ unsigned long flags;
++ u32 dmacnt, dmacnt_chkval, tmpcnt;
++
++ nmdk_dbg_ftrace();
++
++/* if (dma->invalid) {
++ if (dma->mode) {
++ if (((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH) ==
++ (dma->mode & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
++ dmaconfig_mode(dma) = (u32)dma->mode;
++ }
++ }
++ } else {
++ exit_invl_parms:
++ nmdk_error("enable request without parameters");
++ goto exit_en
+ }
++ if (dma->addr) dmaconfig_srcadr(x) = dma->addr;
++ if (dma->speed) dmaconfig_destadr(x) = (u32)dma->speed;
++*/
+
-+ nmdk_dbg("In nomadik_msp_disable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
-+ /*Set global flag to free state*/
-+ switch(msp) {
-+ case 0: if(flag_msp0->user == user) {
-+ down(&flag_msp0->lock);
-+ flag_msp0->user = MSP_NO_USER;
-+ up(&flag_msp0->lock);
-+ nmdk_dbg("Flag cleanup for MSP0\n");
-+ }
-+ else {
-+ nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp0->user);
-+ status = -EFAULT;
-+ }
-+ break;
-+ case 1: if(flag_msp1->user == user) {
-+ down(&flag_msp1->lock);
-+ flag_msp1->user = MSP_NO_USER;
-+ up(&flag_msp1->lock);
-+ nmdk_dbg("Flag cleanup for MSP1\n");
-+ }
-+ else {
-+ nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp1->user);
-+ status = -EFAULT;
-+ }
-+ break;
-+ case 2: if(flag_msp2->user == user) {
-+ down(&flag_msp2->lock);
-+ flag_msp2->user = MSP_NO_USER;
-+ up(&flag_msp2->lock);
-+ nmdk_dbg("Flag cleanup for MSP2\n");
-+ }
-+ else {
-+ nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp2->user);
-+ status = -EFAULT;
-+ }
-+ break;
++ if (!(dma->sg)) {
++ if (!(dma->addr)) {
++ nmdk_error("srcadr not set");
++ goto exit_en;
++ }
++ if (!(dma->speed)) {
++ nmdk_error("destadr not set");
++ goto exit_en;
++ }
+ }
-+ if(status)
-+ return status;
+
-+ if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
-+ goto disable_alt;
-+ }
++ /*set transfer size = count/src_width */
++ dmacnt = dma->count/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
++ nmdk_dbg("total count = %d, dma count =%d",(u32)dma->count, dmacnt);
++ tmpcnt = 0;
++ dmacnt_chkval = 0x0ff0;
+
-+ if (direction != MSP_RECEIVE_MODE) {
-+ int status = nomadik_msp_wait_for_tx_complete(msp);
-+ if (status) {
-+ goto disable_alt;
++ if (dma->sg) {
++ /*Scatter gather list implimentation */
++ if (dma->sgcount == 0) {
++ nmdk_error("Empty scatter gather list");
++ goto exit_en;
+ }
-+ }
-+ switch (direction) {
-+ case MSP_RECEIVE_MODE:
-+ registers[msp]->global_ctrl &= ~RX_ENABLE;
-+ registers[msp]->dma_ctrl &= ~RX_DMA_ENABLE;
-+ registers[msp]->irq_mask &= ~(RECEIVE_SERVICE_INT |
-+ RECEIVE_OVERRUN_ERROR_INT);
-+ rx_status[msp].flow_error_count = 0;
-+ break;
-+ case MSP_TRANSMIT_MODE:
-+ registers[msp]->global_ctrl &= ~TX_ENABLE;
-+ registers[msp]->dma_ctrl &= ~TX_DMA_ENABLE;
-+ registers[msp]->irq_mask &= ~(TRANSMIT_SERVICE_INT |
-+ TRANSMIT_UNDERRUN_ERR_INT);
-+ tx_status[msp].flow_error_count = 0;
-+ break;
-+ case MSP_BOTH_T_R_MODE:
-+ registers[msp]->global_ctrl &= ~(TX_ENABLE | RX_ENABLE);
-+ registers[msp]->dma_ctrl &= ~(TX_DMA_ENABLE | RX_DMA_ENABLE);
-+ registers[msp]->irq_mask &= ~ALL_INT;
-+ tx_status[msp].flow_error_count = 0;
-+ rx_status[msp].flow_error_count = 0;
-+ break;
-+ default:
-+ printk(KERN_ERR "Invalid direction param\n");
-+ status = -EINVAL;
-+ goto disable_alt;
-+ }
++ if ((((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_MEM ) ||
++ (((u32)dmaconfig_mode(dma) & 0x03) == PERIPH_TO_PERIPH )) {
++ nmdk_error("Unsupported mode for scatter gather");
++ goto exit_en;
++ }
++ p_lli_start = nomadik_dma_allocate_llis(dma->sgcount +1);
++ p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
++#ifdef SCATERGATHER_MMC_DEBUG
++ if (dma->sgcount > 1) {
++ dmaconfig_config(dma) |= 0x0f0007fe;
++ nmdk_dbg("sc_count=%d , config=%08x", dma->sgcount, dmaconfig_config(dma));
++ if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
++ printk("===%p", dma_alloc_coherent( NULL , 4096, &dma->speed, GFP_DMA | GFP_KERNEL ));
+
-+ msp_context[msp].msp_disable = 1;
++ } else {
++ printk("==%p",dma_alloc_coherent( NULL , 4096, &dma->addr, GFP_DMA | GFP_KERNEL ));
++ }
++ dmaconfig_mode(dma) = 0;
++ }
++#endif
++ tmpcnt = dma->count;
++ while (dma->sgcount) {
++ nmdk_dbg("tmpcnt %d, sg_len %d", tmpcnt, dma->sg->length);
++ p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
++ if (!(dma->sg->dma_address)) {
++ nmdk_error("sg list not dma mapped");
++ goto exit_en;
++ }
++ if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
++ p_lli_curr->mem1.sadr = dma->sg->dma_address;
++ if (!(dma->speed)) {
++ nmdk_error("destadr not set");
++ goto exit_en;
++ }
++ p_lli_curr->mem2.dadr = (dma_addr_t)dma->speed;
++ } else {
++ if (!(dma->addr)) {
++ nmdk_error("srcadr not set");
++ goto exit_en;
++ }
++ p_lli_curr->mem1.sadr = (dma_addr_t)dma->addr;
++ p_lli_curr->mem2.dadr = dma->sg->dma_address;
++ }
++ if (tmpcnt > dma->sg->length) {
++ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++ (dma->sg->length/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
++ } else {
++ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++ (tmpcnt/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
++ }
++ tmpcnt -= dma->sg->length;
++ dma->sgcount--; dma->sg++;
++ if (dma->sgcount == 0) p_lli_curr->mem4.cr |= (1<<31);
++ p_lli_curr = p_lli_next;
++ }
++ } else if ((u32)dmaconfig_mode(dma) & DMA_DOUBLE_BUFFERED ) {
++ p_lli_start = nomadik_dma_allocate_llis(3);
++ p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
++ p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
+
-+ if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
-+ /* disable sample rate and frame generators */
-+ registers[msp]->global_ctrl &= ~(FRAME_GEN_ENABLE | SRG_ENABLE);
++ dmacnt /= 2;
++ dmacnt_chkval = dmacnt;
++ /*fill next lli structure */
++ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | dmacnt_chkval);
++ p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
++ p_lli_curr->mem2.dadr = dma->speed;
++ p_lli_next->mem4.cr = p_lli_curr->mem4.cr;
++ p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
++ p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
++ if (p_lli_next->mem4.cr & DMA_ADR_INC) p_lli_next->mem1.sadr += dma->count/2;
++ if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1)) p_lli_next->mem2.dadr += dma->count/2;
+
-+ free_irq(msp_irq, (void *)registers[msp]);
-+ }
++ if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
++ p_lli_next->mem3.next = p_lli_start->mem3.p_lli_hw;
++ } else {
++ p_lli_next->mem4.cr |= (1<<31);
++ }
++ } /*mode & DMA_DOUBLE_BUFFERED*/
++ else {
++ tmpcnt = dmacnt/dmacnt_chkval;
++ p_lli_start = nomadik_dma_allocate_llis(tmpcnt + 2);
++ p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
++ p_lli_next = p_lli_curr;
+
++ p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++ ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
++ dmacnt -= dmacnt_chkval;
++ p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
++ p_lli_curr->mem2.dadr = dma->speed;
++ while(tmpcnt) {
++ p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
++ /*fill next lli structure */
++ p_lli_next->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++ ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
++ p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
++ p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
++ if (p_lli_next->mem4.cr & DMA_ADR_INC)
++ p_lli_next->mem1.sadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
++ if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1))
++ p_lli_next->mem2.dadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
+
-+disable_alt:
-+ switch (msp) {
-+ case 0:
-+ nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_0");
-+ break;
-+ case 1:
-+ nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_1");
-+ break;
-+ case 2:
-+ nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_2");
-+ break;
++ p_lli_curr = p_lli_next;
++ dmacnt -= dmacnt_chkval;
++ tmpcnt--;
++ }
++ p_lli_curr->mem4.cr |= (1<<31);
++ if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
++ p_lli_curr->mem3.next = p_lli_start->mem3.p_lli_hw;
++ } else {
++ p_lli_curr->mem4.cr |= (1<<31);
+ }
++ }
++ nmdk_dbg("lli_start(%p)", p_lli_start);
++ p_lli_start->mem2.dma = (void *)dma; /*dma associated with this lii*/
++ p_lli_start->mem4.cfg = (((u32)dmaconfig_config(dma) & 0x000007fe) | /* set src/dest dma periph request line numbers */
++ ((u32)dmaconfig_mode(dma)<<11 & (7<<11)) | /* set flow control and xter type*/
++ (0x0000c001)); /*enable interrupts and start xfer*/
+
-+ return status;
++ /* if channel is reserved use predefined hwpipe else find free
++ * h/w pipe to schedule dma
++ * if h/w pipe is not available the que the request
++ */
++ if (!((u32)dmaconfig_pipeadr(dma))) {
++ dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
++ if (dmaconfig_pipeadr(dma)) {
++ nmdk_dbg("channel %d allocated pipe p_dmach_reg(%p) ",channel, (void *)dmaconfig_pipeadr(dma));
++ } else {
++ nmdk_error("enable requested aborted...No pipe available...");
++ goto exit_en;
++ }
++ }
++ /* program dmach irqname if not set by client */
++ if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
++ if (!(socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name))
++ socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name =
++ (dmach_name + (channel * MAX_DMA_CHNAME_SIZE));
++
++ mb();
++ flags = claim_dma_lock();
++ nomadik_dma_schedule_xfer_on_pipe((void *)dmaconfig_pipeadr(dma), p_lli_start);
++ release_dma_lock(flags);
++ dma->state = NMDK_DMA_ENABLED;
++ if ((u32)dmaconfig_mode(dma) & DMA_QUEUE_ENABLED) dma->active = 0;
++ return;
++
++exit_en:
++ if (p_lli_start) nomadik_dma_deallocate_llis(p_lli_start);
++ return;
+}
+
-+static int configure_protocol(int msp, int protocol, int direction,
-+ enum msp_data_size data_size)
++/**
++ * nomadik_dma_dis - low level method for disable_dma API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * disables a transfer on a pipe if associated with a requested channel
++ */
++static void nomadik_dma_dis(dmach_t channel, dma_t *dma)
+{
-+ u32 temp_reg;
++ struct dmach_register *p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++ unsigned long flags;
+
-+ if ((protocol < 0) || (protocol >= MSP_INVALID_PROTOCOL)) {
-+ printk(KERN_ERR
-+ "invalid protocol requested in configure_protocol()\n");
-+ return -EINVAL;
-+ }
++ nmdk_dbg_ftrace();
+
-+ if (data_size < MSP_DATA_SIZE_DEFAULT
-+ || data_size > MSP_DATA_SIZE_32BIT) {
-+ printk(KERN_ERR
-+ "invalid data size requested in configure_protocol()\n");
-+ return -EINVAL;
-+ }
++ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
++ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++ flags = claim_dma_lock();
++ nmdk_dbg("Channel %d disabled on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++ p_dmach_reg->cfg &= ~0x0000c001;
++ release_dma_lock(flags);
++ dma->state = NMDK_DMA_DISABLED;
++}
+
-+ switch (direction) {
-+ case MSP_TRANSMIT_MODE:
-+ tx_status[msp].phase_mode =
-+ protocol_desc_tab[protocol].phase_mode;
++static void nomadik_dma_fr(dmach_t channel, dma_t *dma)
++{
++ nmdk_dbg_ftrace();
++ nomadik_dma_dis(channel, dma);
++ if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
++ free_irq(IRQNO_FOR_DMACH(channel), socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->dev_id);
++ if (dmaconfig_pipeadr(dma)) nomadik_dma_flush_pipe((void *)dmaconfig_pipeadr(dma));
++}
+
-+ /* Use a temp for setup. Clear everything except the two non-mode
-+ * dependent bits, then add back the bits for the selected protocol
-+ */
-+ temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
++/* find the available dma chanel and requests the same */
++/**
++ * request_available_dma - Wrapper over request_dma API
++ * @dmach_config_info: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Wrapper over request_dma API for free and available DMA channel search
++ * returns DMA Channel number , negative error value in case of failure
++ */
++int request_available_dma(struct nmdk_dma_info * dmach_config_info)
++{
++ dmach_t channel;
++ int error;
+
-+ temp_reg |=
-+ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+ temp_reg |=
-+ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_1);
-+ temp_reg |=
-+ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_2);
-+ if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+ temp_reg |=
-+ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_1);
-+ temp_reg |=
-+ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_2);
-+ if (protocol_desc_tab[protocol].element_len_1 ==
-+ protocol_desc_tab[protocol].element_len_2) {
-+ msp_context[msp].actual_data_size =
-+ protocol_desc_tab[protocol].element_len_1;
-+ } else {
-+ msp_context[msp].actual_data_size = data_size;
-+ }
++ /*removed locks as detected by spinlock debugging on*/
++ for (channel = 0; channel < (MAX_DMA_CHANNELS - 1); channel++) {
++ error = request_dma(channel, (char *)dmach_config_info);
++ if (-EBUSY == error) continue;
++ if (error < 0) {
++ nmdk_error("Request DMA error");
++ return error;
+ } else {
-+ temp_reg |= msp_p1_elem_len_bits(data_size);
-+ temp_reg |= msp_p2_elem_len_bits(data_size);
-+ msp_context[msp].actual_data_size = data_size;
++ nmdk_dbg("Dma Chanel %d is available and allocated", channel);
++ return channel;
+ }
-+ temp_reg |=
-+ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
-+
-+ (registers[msp]->tx_config) = temp_reg;
-+
-+ /* The tx_config register is done, now set the clock mode (rising
-+ * or falling edge). We first clear the bit using the ~RISING value.
-+ */
-+ temp_reg = (registers[msp]->global_ctrl) & ~TX_CLK_POL_RISING;
-+ temp_reg |=
-+ msp_tx_clkpol_bit(protocol_desc_tab[protocol].
-+ tx_clock_edge);
-+ temp_reg |= TX_EXTRA_DELAY_ENABLE;
-+ temp_reg |= msp_data_delay_bits(MSP_DELAY_1);
++ }
++ nmdk_error("All DMA Channels occupied....");
++ return -DMA_ALLCHANELS_OCCUPIED;
++}
++EXPORT_SYMBOL(request_available_dma);
+
-+ (registers[msp]->global_ctrl) = temp_reg;
-+ break;
-+ case MSP_RECEIVE_MODE:
-+ rx_status[msp].phase_mode =
-+ protocol_desc_tab[protocol].phase_mode;
++/**
++ * suspend_dma - Pauses DMA transfer for this channel
++ * @channel: DMA channel number
++ *
++ * This API will pause current dma if it is ongoing
++ * also this API is used to pause all active on going DMA channels involved
++ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
++ */
++void suspend_dma(dmach_t channel)
++{
++ dma_t *dma;
++ volatile struct dmach_register *p_dmach_reg;
++ unsigned long flags;
+
-+ /* Use a temp for setup. Clear everything except the two non-mode
-+ * dependent bits, then add back the bits for the selected protocol
-+ */
-+ temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
++ nmdk_dbg_ftrace();
++ if (!(socdat->dma_chan)) goto inactive_dma;
++ dma = socdat->dma_chan;
++ if (DMA_ALL_MEM_CHANNELS == channel) {
++ for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
++ if (!dma->lock) continue;
++ if (NMDK_DMA_SUSPENDED == dma->state) continue;
++ if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
++ == PERIPH_TO_PERIPH) continue;
++ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
+
-+ temp_reg |=
-+ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+ temp_reg |=
-+ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_1);
-+ temp_reg |=
-+ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_2);
-+ if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+ temp_reg |=
-+ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_1);
-+ temp_reg |=
-+ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_2);
-+ if (protocol_desc_tab[protocol].element_len_1 ==
-+ protocol_desc_tab[protocol].element_len_2) {
-+ msp_context[msp].actual_data_size =
-+ protocol_desc_tab[protocol].element_len_1;
-+ } else {
-+ msp_context[msp].actual_data_size = data_size;
++ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
++ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++ flags = claim_dma_lock();
++ nmdk_dbg("Channel %d Suspended on pipe %p", channel, (void *)dmaconfig_pipeadr(dma));
++ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++ p_dmach_reg->cfg |= NMDK_DMACH_HALT;
+ }
-+ } else {
-+ temp_reg |= msp_p1_elem_len_bits(data_size);
-+ temp_reg |= msp_p2_elem_len_bits(data_size);
-+ msp_context[msp].actual_data_size = data_size;
++ release_dma_lock(flags);
++ dma->state = NMDK_DMA_SUSPENDED;
++
++ dma++;
+ }
-+ temp_reg |=
-+ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
++ return;
++ }
++ if (!(socdat->dma_chan)) goto inactive_dma;
++ dma += channel;
++ if (!dma->lock)
++ goto free_dma;
+
-+ (registers[msp]->rx_config) = temp_reg;
++ if (NMDK_DMA_SUSPENDED == dma->state) return;
++ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
+
-+ /* The rx_config register is done, now set the clock mode (rising
-+ * or falling edge). We first clear the bit using the ~RISING value.
-+ */
-+ temp_reg = (registers[msp]->global_ctrl) & ~RX_CLK_POL_RISING;
-+ temp_reg |=
-+ msp_rx_clkpol_bit(protocol_desc_tab[protocol].
-+ rx_clock_edge);
++ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
++ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++ flags = claim_dma_lock();
++ nmdk_dbg("Channel %d Suspended on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++ p_dmach_reg->cfg |= NMDK_DMACH_HALT;
++ }
++ release_dma_lock(flags);
++ dma->state = NMDK_DMA_SUSPENDED;
++ return;
+
-+ (registers[msp]->global_ctrl) = temp_reg;
-+ break;
-+ case MSP_BOTH_T_R_MODE:
-+ rx_status[msp].phase_mode =
-+ protocol_desc_tab[protocol].phase_mode;
-+ tx_status[msp].phase_mode =
-+ protocol_desc_tab[protocol].phase_mode;
++free_dma:
++ printk(KERN_ERR "dma%d: trying to suspend free DMA\n", channel);
++ BUG();
++ return;
++inactive_dma:
++ printk(KERN_ERR "dma driver not active\n");
++ BUG();
++}
++EXPORT_SYMBOL(suspend_dma);
+
-+ /* Use a temp for setup. Clear everything except the two non-mode
-+ * dependent bits, then add back the bits for the selected protocol
-+ * do rx_config first
-+ */
-+ temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
+
-+ temp_reg |=
-+ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+ temp_reg |=
-+ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_1);
-+ temp_reg |=
-+ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_2);
-+ if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+ temp_reg |=
-+ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_1);
-+ temp_reg |=
-+ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_2);
-+ if (protocol_desc_tab[protocol].element_len_1 ==
-+ protocol_desc_tab[protocol].element_len_2) {
-+ msp_context[msp].actual_data_size =
-+ protocol_desc_tab[protocol].element_len_1;
-+ } else {
-+ msp_context[msp].actual_data_size = data_size;
-+ }
-+ } else {
-+ temp_reg |= msp_p1_elem_len_bits(data_size);
-+ temp_reg |= msp_p2_elem_len_bits(data_size);
-+ msp_context[msp].actual_data_size = data_size;
-+ }
-+ temp_reg |=
-+ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
++/**
++ * nomadik_dma_residue - low level method for get_dma_residue API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Pause the channel, read the control register, resume the channel
++ * May not be an accurate value
++ * returns bytes remaining on a transfer
++ */
++static int nomadik_dma_residue(dmach_t channel, dma_t *dma)
++{
++ volatile unsigned int r = 0;
++ volatile struct dmach_register *p_dmach_reg =
++ (struct dmach_register *)dmaconfig_pipeadr(dma);
+
-+ (registers[msp]->rx_config) = temp_reg;
++ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return -1;
++ suspend_dma(channel);
++ mb();
+
-+ /* Now tx_config */
-+ temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
++ /*get transfer bytes = src_width * transfer_size */
++ r = p_dmach_reg->cr & 0x0fff;
++ r *= ((p_dmach_reg->cr & 0x000c0000)>>17);
++ mb();
++ resume_dma(channel);
++
++ return r;
++}
++
++/**
++ * resume_dma - Resume already suspended DMA transfer for this channel
++ * @channel: DMA channel number
++ *
++ * This API will resume current dma if it is suspended previously
++ * also this API is used to resume all active and paused DMA channels involved
++ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
++ */
++void resume_dma(dmach_t channel)
++{
++ dma_t *dma;
++ volatile struct dmach_register *p_dmach_reg;
++ unsigned long flags;
++
++ nmdk_dbg_ftrace();
++ if (!(socdat->dma_chan)) goto inactive_dma;
++ dma = socdat->dma_chan;
++ if (DMA_ALL_MEM_CHANNELS == channel) {
++ for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
++ if (!dma->lock) continue;
++ if (NMDK_DMA_SUSPENDED != dma->state) continue;
++ if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
++ == PERIPH_TO_PERIPH) continue;
++ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++
++ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
++ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++ flags = claim_dma_lock();
++ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++ p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
++ }
++ nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++ release_dma_lock(flags);
++ dma->state = NMDK_DMA_RESUMED;
+
-+ temp_reg |=
-+ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+ temp_reg |=
-+ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_1);
-+ temp_reg |=
-+ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+ frame_len_2);
-+ if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+ temp_reg |=
-+ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_1);
-+ temp_reg |=
-+ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+ element_len_2);
-+ } else {
-+ temp_reg |= msp_p1_elem_len_bits(data_size);
-+ temp_reg |= msp_p2_elem_len_bits(data_size);
+ }
-+ temp_reg |=
-+ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
++ return;
++ }
++ dma += channel;
++ if (!dma->lock)
++ goto free_dma;
+
-+ (registers[msp]->tx_config) = temp_reg;
-+ /* The [rt]x_config register is done, now set the clock mode (rising
-+ * or falling edge). We first clear the bit using the ~RISING value.
-+ */
-+ temp_reg =
-+ (registers[msp]->
-+ global_ctrl) & ~(TX_CLK_POL_RISING | RX_CLK_POL_RISING);
-+ temp_reg |=
-+ msp_rx_clkpol_bit(protocol_desc_tab[protocol].
-+ rx_clock_edge);
-+ temp_reg |=
-+ msp_tx_clkpol_bit(protocol_desc_tab[protocol].
-+ tx_clock_edge);
++ if (NMDK_DMA_SUSPENDED != dma->state) return;
++ p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
+
-+ (registers[msp]->global_ctrl) = temp_reg;
-+ break;
-+ default:
-+ printk(KERN_ERR "Invalid direction given\n");
-+ return -EINVAL;
++ if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
++ /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++ flags = claim_dma_lock();
++ if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++ p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
+ }
++ nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++ release_dma_lock(flags);
++ dma->state = NMDK_DMA_RESUMED;
++ return;
+
-+ return 0;
++free_dma:
++ printk(KERN_ERR "dma%d: trying to resume free DMA\n", channel);
++ BUG();
++ return;
++inactive_dma:
++ printk(KERN_ERR "dma driver not active\n");
++ BUG();
+}
++EXPORT_SYMBOL(resume_dma);
+
-+static int configure_clock(int msp, int protocol, u32 input_clock,
-+ u32 frame_freq, int frame_size)
++/**
++ * nomadik_dma_set_destadr - low level method for set_dma_speed API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ * @cycle: sonsidered as destination DMA address
++ *
++ * Since ther is no API to program destination DMA address.
++ * set_dma_speed is used to fulfill this need.
++ * the function returnes the cycle which finally programs dma->spped
++ * with destination DMA address for nomadik platform
++ */
++static int nomadik_dma_set_destadr(dmach_t channel, dma_t *dma, int cycle)
+{
-+ u32 dummy;
-+ u32 frame_per = 0;
-+ u32 sck_div = 0;
-+ u32 frame_width = 0;
-+ u32 temp_reg = 0;
-+ u32 data_size;
-+
-+ (registers[msp]->global_ctrl) &= ~SRG_ENABLE;
-+
-+ switch (msp_context[msp].actual_data_size) {
-+ case MSP_DATA_SIZE_8BIT:
-+ data_size = 8;
-+ break;
-+ case MSP_DATA_SIZE_10BIT:
-+ data_size = 10;
-+ break;
-+ case MSP_DATA_SIZE_12BIT:
-+ data_size = 12;
-+ break;
-+ case MSP_DATA_SIZE_14BIT:
-+ data_size = 14;
-+ break;
-+ case MSP_DATA_SIZE_16BIT:
-+ data_size = 16;
-+ break;
-+ case MSP_DATA_SIZE_20BIT:
-+ data_size = 20;
-+ break;
-+ case MSP_DATA_SIZE_24BIT:
-+ data_size = 24;
-+ break;
-+ case MSP_DATA_SIZE_32BIT:
-+ data_size = 32;
-+ break;
-+ default:
-+ printk(KERN_ERR
-+ "Unable to determine data size in configure_clock\n");
-+ return -EINVAL;
-+ }
++ /*Speed is used to store destination address*/
++ return (cycle);
++}
+
-+ switch (protocol) {
-+ case MSP_PCM_PROTOCOL:
-+ case MSP_PCM_COMPAND_PROTOCOL:
-+ case MSP_MASTER_SPI_PROTOCOL:
-+ if (frame_size < 0) {
-+ frame_per = data_size;
-+ if (protocol == MSP_MASTER_SPI_PROTOCOL) {
-+ /* Need 1 clock between start of frame and start
-+ * of data, and 1 clock to indicate end of frame
-+ */
-+ frame_per += 2;
++/**
++ * nomadik_dma_interrupt - Interrupt handler for DMA controller
++ * @irq: interrupt request number
++ * @desc: irq structure pointer
++ *
++ * checks and find out the source DMA channel who generated interrupt
++ * if interrupt generated is Terminal count then
++ * process the DMA chanel irq associated with a pipe
++ * if interrupt generated is Bus_error then
++ * just acknowledge it.
++ * free processed transfer lli and schedule the queue
++ */
++static void nomadik_dma_interrupt(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
++{
++ u32 mask;
++ volatile struct dma_register *p_dma_reg = (struct dma_register *)desc->chip_data;
++ volatile struct dmach_register *p_dmach_reg;
++ struct dma_struct *di_dmachan;
++ do {
++ p_dmach_reg = &p_dma_reg->dmach[0];
++ nmdk_dbg2("dhach addr = %p", p_dmach_reg);
++ for (mask = 1; mask != 0x100; mask=mask<<1) {
++ if (p_dma_reg->mis & mask) {
++ /* To wait for the physical Channel to get disabled(otherwise it may
++ cause Virtual/Spurious Interrupts) */
++ while (nomadik_dmach_is_active_n_enabled(p_dmach_reg->cfg)) ;
++ if (p_dma_reg->tcmis & mask) {
++ p_dma_reg->tcicr |= mask;
++ irq = nomadik_dma_channel_of_pipe((void *)p_dmach_reg);
++ if (irq != 0) {
++ desc = socdat->dirqdesc + irq;
++ di_dmachan = socdat->dma_chan + DMACH_FOR_IRQNO(irq);
++ /*handle dmachanel interrupt callback*/
++ nmdk_dbg3("ch%d tc intr", DMACH_FOR_IRQNO(irq));
++ /*flag upper layer to that requested dma is complete*/
++ if (di_dmachan->active) di_dmachan->active = 0;
++ desc_handle_irq(irq, desc);
++ /*free lli of processed request and schedule if any request in queue*/
++ nomadik_dma_free_procesed_pipe(p_dmach_reg);
++ }
++ }
++ if (p_dma_reg->emis & mask) {
++ p_dma_reg->eicr |= mask;
++ nmdk_error("Intr buserr for pipe %08x", (u32)p_dmach_reg);
++ nomadik_dma_free_procesed_pipe(p_dmach_reg);
++ }
+ }
-+ } else {
-+ frame_per = data_size;
-+ }
-+ if (frame_per < data_size) {
-+ printk(KERN_ERR
-+ "Frame size too small in configure_clock\n");
-+ return -EINVAL;
++ p_dmach_reg++;
+ }
-+ frame_width = 1;
++ } while (p_dma_reg->mis != 0);
++ nmdk_dbg2("intr exit");
++}
+
-+ sck_div = input_clock / (frame_freq << 8);
-+ frame_per = MSP_FRAME_PERIOD_IN_MONO_MODE;
++struct dma_ops nomadik_dma_ops = {
++ .type = "DMACH:",
++ .request = nomadik_dma_req,
++ .free = nomadik_dma_fr,
++ .enable = nomadik_dma_en,
++ .disable = nomadik_dma_dis,
++ .setspeed = nomadik_dma_set_destadr,
++ .residue = nomadik_dma_residue,
++};
+
-+ break;
-+ case MSP_I2S_PROTOCOL:
-+ sck_div = input_clock / (frame_freq << 5);
-+ frame_per = MSP_FRAME_PERIOD_IN_STEREO_MODE;
-+ frame_width = MSP_FRAME_WIDTH_IN_STEREO_MODE;
++/**
++ * nomadik_dma_probe - driver probe function
++ *
++ * checks platfom_data is programmed properly
++ * ioremaps the DMAC register and updates pointer
++ * sets DMAC irq handler
++ * allocates memory for lli pool
++ * configures DMA channels and DMA channel interrupts
++ */
++static int nomadik_dma_probe(struct amba_device *dev, void *data)
++{
++ int i, ret;
++ uint8 dmac;
++ struct irq_desc *dirq_desc;
++ struct dma_struct *dmachan, *dmachan_temp;
++ volatile struct dma_register *p_dma_reg;
++ struct irqchip *p_dirqchip;
+
-+ break;
-+ case MSP_AC97_PROTOCOL:
-+ /* Not supported */
-+ printk(KERN_WARNING "AC97 protocol not supported\n");
-+ return -ENOSYS;
-+ case MSP_SLAVE_SPI_PROTOCOL:
-+ sck_div = 1;
-+ break;
-+ default:
-+ printk(KERN_ERR "Invalid mode attempted for setting clocks\n");
-+ return -EINVAL;
++ nmdk_dbg_ftrace();
++
++ /* findout dma controller number*/
++ if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
++ else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
++ else {
++ nmdk_error("invalid dma device");
++ ret = -EINVAL;
++ goto res_out;
+ }
+
-+ temp_reg = (sck_div - 1) & SCK_DIV_MASK;
-+ temp_reg |= frame_width_bits(frame_width - 1);
-+ temp_reg |= frame_period_bits(frame_per - 1);
-+ registers[msp]->srg_ctrl = temp_reg;
++ if (! dev->dev.platform_data) {
++ nmdk_error("platform specific data no initialized for DMAC%d", dmac);
++ ret = -ENOMEM;
++ goto res_out;
++ }
++/* ret = amba_request_regions(dev, NULL);
++ if (ret)
++ goto out;
++ */
++ p_dma_reg = (void __iomem *)
++ ioremap((int)dev->res.start, SZ_4K);
++ if (!p_dma_reg) {
++ nmdk_error("ioremap failed for DMAC%d", dmac);
++ ret = -ENOMEM;
++ goto res_out;
++ }
++ nmdk_dbg("dma_erg prt = %p irq %d", p_dma_reg,dev->irq[0] );
++ socdat = (struct dma_soc_data *)dev->dev.platform_data;
++ dmachan = (struct dma_struct *)socdat->dma_chan;
++ dirq_desc = socdat->dirqdesc;
++ p_dirqchip = socdat->dirqchip;
++ dirq_desc[dev->irq[0]].chip_data = (void *)p_dma_reg;
+
-+ /* Wait a bit */
-+ dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
++ memset((void *)p_dma_reg, 0, sizeof(struct dma_register)); /*init h/w register to zero*/
++#ifdef __STN_8810
++#if (__STN_8810 == 10)
++ p_dma_reg->cr = 0x01; /*enable DMa controller */
++#endif
++#endif
+
-+ /* Enable clock */
-+ registers[msp]->global_ctrl |= SRG_ENABLE;
++ set_irq_chained_handler(dev->irq[0], (void *)nomadik_dma_interrupt);
+
-+ /* Another wait */
-+ dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
-+ /* reconfigure spi clock mode */
-+ temp_reg = registers[msp]->global_ctrl;
-+ temp_reg &= ~SPI_CLK_MODE_MASK;
-+ temp_reg |= spi_clock_mode[msp];
-+ temp_reg &= ~SPI_BURST_MODE_MASK;
-+ temp_reg |= spi_burst_mode[msp];
++ if (!(dmac)) {
+
-+ registers[msp]->global_ctrl = temp_reg;
-+ return 0;
++ lli_ptr_log = (struct dmach_lli *)dma_alloc_coherent(NULL,
++ MAX_DMA_LLIS * (sizeof(struct dmach_lli)),
++ (dma_addr_t *) &lli_ptr_phy,
++ GFP_DMA | GFP_ATOMIC);
++ if (lli_ptr_log <= 0) {
++ nmdk_error("unable to request mem for llis");
++ ret = -1;
++ goto bad_dev;
++ }
++ nmdk_info("chanel lli physical adr(%08x) logical adr(%08x)", (u32)lli_ptr_phy, (u32)lli_ptr_log);
++ dmachan_temp = dmachan;
++ /* dma chanel irq initialization */
++ for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
++ /*set_irq_chip(i, &nomadik_dma_chip);*/
++ set_irq_handler(i, handle_simple_irq);
++ set_irq_flags(i, IRQF_VALID);
++ socdat->dirqdesc[i].chip_data= NULL; //&p_dma_reg->dmach[ret];
++ if (i < MAX_DMA_CHANNELS) p_lli_pipe[DMACH_FOR_IRQNO(i)] = NULL;
++ /* dma chanel data structure initialization */
++ dmachan[DMACH_FOR_IRQNO(i)].d_ops = &nomadik_dma_ops;
++ dmachan[DMACH_FOR_IRQNO(i)].dma_irq = i;
++
++ }
++ }
++ nmdk_info("DMA%d Module initialized Ver("DMA_VER")",dmac);
++ return (0);
++
++bad_dev:
++ iounmap(p_dma_reg);
++res_out:
++ return (ret);
+}
+
-+static irqreturn_t handle_irq(int irq, void *dev_id)
++/**
++ * nomadik_dma_remove - driver remove function
++ *
++ * resets DMA channels and DMA channel interrupts configureation
++ * deallocates memory for lli pool
++ * resets DMAC irq handler
++ * frees ioremapped memory
++ */
++static int nomadik_dma_remove(struct amba_device *dev)
+{
-+ int msp;
-+ u32 irq_status;
++ uint8 dmac;
++ int i;
++ struct irq_desc *dirq_desc;
++ struct dma_struct *dma_chan;
++ volatile struct dma_register *p_dma_reg;
++ struct irqchip *p_dirqchip;
+
-+ /* dev_id should be the register base address, find out which MSP
-+ * we are dealing with. */
-+ for (msp = 0; msp < MSP_COUNT; msp++) {
-+ if (dev_id == registers[msp]) {
-+ break;
-+ }
++ nmdk_dbg_ftrace();
++
++ /* findout dma controller number*/
++ if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
++ else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
++ else {
++ nmdk_error("invalide dma device");
++ return(-EINVAL);
+ }
++ socdat = dev->dev.platform_data;
++ dma_chan = (struct dma_struct *)socdat->dma_chan;
++ dirq_desc = socdat->dirqdesc;
++ p_dma_reg = dirq_desc[dev->irq[0]].chip_data;
+
-+ if (msp == MSP_COUNT) {
-+ /* Didn't find the MSP, this must not be our interrupt */
-+ return -1;
++ p_dirqchip = socdat->dirqchip;
++ if (!(dmac)) {
++ for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
++ //set_irq_chip(i, 0x00);
++ set_irq_handler(i, handle_bad_irq);
++ dma_chan[DMACH_FOR_IRQNO(i)].d_ops = NULL;
++ }
+ }
+
-+ irq_status = registers[msp]->masked_irq_status;
++ set_irq_handler(dev->irq[0], handle_bad_irq);
+
-+ /* Disable the interrupt to prevent immediate recurrence */
-+ registers[msp]->irq_mask &= ~irq_status;
++ dma_free_coherent(NULL,
++ ((MAX_DMA_CHANNELS*(sizeof(struct dmach_lli))*8)+256),
++ (void *)lli_ptr_log, (dma_addr_t)lli_ptr_phy );
++ lli_ptr_phy = lli_ptr_log = NULL;
+
-+ /* Clear the interrupt */
-+ registers[msp]->irq_clear = irq_status;
++ iounmap(p_dma_reg);
++ dirq_desc[dev->irq[0]].chip_data = 0x00;
++ /*amba_release_regions(dev);*/
+
-+ /* Check for an error condition */
-+ msp_io_error[msp] |= irq_status & (RECEIVE_OVERRUN_ERROR_INT |
-+ RECEIVE_FRAME_SYNC_ERR_INT |
-+ TRANSMIT_UNDERRUN_ERR_INT |
-+ TRANSMIT_FRAME_SYNC_ERR_INT);
++ nmdk_info("Module removed");
++ return 0;
++}
+
-+ /* Wake up the reader/writer */
-+ wake_up_interruptible(&wait[msp]);
-+ return IRQ_HANDLED;
++static struct amba_id nomadik_dma_dev_ids[] __initdata = {
++ {
++ .id = DMA_PER_ID,
++ .mask = DMA_PER_MASK,
++ },
++ {0, 0},
++};
+
-+}
++static struct amba_driver dma_driver = {
++ .drv = {
++ .name = "DMA",
++ },
++ .id_table = nomadik_dma_dev_ids,
++ .probe = nomadik_dma_probe,
++ .remove = nomadik_dma_remove
++};
+
-+static int transmit_data(int msp, void *data, size_t bytes)
++static int __init nomadik_dma_init(void)
+{
-+ return transmit_receive_data(msp, tx_status[msp].work_mode,
-+ data, bytes, NULL, 0);
++ return amba_driver_register(&dma_driver);
+}
+
-+static int receive_data(int msp, void *data, size_t bytes)
++static void __exit nomadik_dma_exit(void)
+{
-+ return transmit_receive_data(msp, rx_status[msp].work_mode,
-+ NULL, 0, data, bytes);
++ amba_driver_unregister(&dma_driver);
+}
+
-+static int transmit_receive_data(int msp, int work_mode,
-+ void *txdata, size_t txbytes,
-+ void *rxdata, size_t rxbytes)
-+{
-+ int status;
-+ u32 tx_offset = 0;
-+ u32 rx_offset = 0;
-+ u8 *data_src_8bit, *data_dst_8bit;
-+ u16 *data_src_16bit, *data_dst_16bit;
-+ u32 *data_src_32bit, *data_dst_32bit;
++module_init(nomadik_dma_init);
++module_exit(nomadik_dma_exit);
+
-+ if (txdata == NULL && txbytes > 0) {
-+ printk(KERN_ERR
-+ "transmit_receive_data received a NULL transmit buffer with bytes to transmit\n");
-+ return -EINVAL;
-+ }
++/* Module parameters */
+
-+ if (rxdata == NULL && rxbytes > 0) {
-+ printk(KERN_ERR
-+ "transmit_receive_data received a NULL receive buffer with bytes to receive\n");
-+ return -EINVAL;
-+ }
++MODULE_AUTHOR("ST Microelectronics");
++MODULE_DESCRIPTION("Nomadik DMA Controllers (0 and 1)");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/fsmc.c
+@@ -0,0 +1,113 @@
++/*
++ * linux/arch/arm/mach-nomadik/fsmc.c
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
+
-+ data_src_8bit = (u8 *) txdata;
-+ data_src_16bit = (u16 *) txdata;
-+ data_src_32bit = (u32 *) txdata;
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <asm/io.h>
++#include <asm/types.h>
++#include <asm/hardware.h>
++#include <asm/arch/fsmc.h>
+
-+ data_dst_8bit = (u8 *) rxdata;
-+ data_dst_16bit = (u16 *) rxdata;
-+ data_dst_32bit = (u32 *) rxdata;
++struct fsmc_nomadik_info {
++ unsigned char __iomem *fsmc_reg;
++};
+
-+ msp_io_error[msp] = 0;
++static int nomadik_fsmc_probe(struct platform_device *pdev)
++{
++ struct fsmc_platform_data *pdata = pdev->dev.platform_data;
++ struct fsmc_nomadik_info *data = NULL;
++ struct resource *res = NULL;
++ if (!pdata->init) {
++ printk("FSMC ::: platform init() function is not present\n");
++ return (-1);
++ }
+
-+ while (tx_offset < txbytes || rx_offset < rxbytes) {
-+ if (msp_io_error[msp]) {
-+ return -EIO;
-+ }
-+
-+ if (rx_offset < rxbytes &&
-+ !((registers[msp]->status) & RX_FIFO_EMPTY)) {
-+ switch (msp_context[msp].actual_data_size) {
-+ case MSP_DATA_SIZE_8BIT:
-+ rx_offset += sizeof(*data_dst_8bit);
-+ *data_dst_8bit++ = registers[msp]->fifo;
-+ break;
-+ case MSP_DATA_SIZE_10BIT:
-+ case MSP_DATA_SIZE_12BIT:
-+ case MSP_DATA_SIZE_14BIT:
-+ case MSP_DATA_SIZE_16BIT:
-+ rx_offset += sizeof(*data_dst_16bit);
-+ *data_dst_16bit++ = registers[msp]->fifo;
-+ break;
-+ case MSP_DATA_SIZE_20BIT:
-+ case MSP_DATA_SIZE_24BIT:
-+ case MSP_DATA_SIZE_32BIT:
-+ rx_offset += sizeof(*data_dst_32bit);
-+ *data_dst_32bit++ = registers[msp]->fifo;
-+ break;
-+ default:
-+ printk(KERN_ERR
-+ "Unable to determine data size in transmit_receive_data\n");
-+ return -EIO;
-+ }
-+ }
-+
-+ if (tx_offset < txbytes &&
-+ !((registers[msp]->status) & TX_FIFO_FULL)) {
-+ switch (msp_context[msp].actual_data_size) {
-+ case MSP_DATA_SIZE_8BIT:
-+ tx_offset += sizeof(*data_src_8bit);
-+ registers[msp]->fifo = *data_src_8bit++;
-+ break;
-+ case MSP_DATA_SIZE_10BIT:
-+ case MSP_DATA_SIZE_12BIT:
-+ case MSP_DATA_SIZE_14BIT:
-+ case MSP_DATA_SIZE_16BIT:
-+ tx_offset += sizeof(*data_src_16bit);
-+ registers[msp]->fifo = *data_src_16bit++;
-+ break;
-+ case MSP_DATA_SIZE_20BIT:
-+ case MSP_DATA_SIZE_24BIT:
-+ case MSP_DATA_SIZE_32BIT:
-+ tx_offset += sizeof(*data_src_32bit);
-+ registers[msp]->fifo = *data_src_32bit++;
-+ break;
-+ default:
-+ printk(KERN_ERR
-+ "Unable to determine data size in transmit_receive_data\n");
-+ return -EIO;
-+ }
-+ }
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
-+ if (work_mode == MSP_INTERRUPT_MODE &&
-+ (tx_offset < txbytes || rx_offset < rxbytes)) {
-+ u32 status_mask = 0;
-+ u32 irq_mask = 0;
-+ if (tx_offset < txbytes) {
-+ status_mask |= TX_FIFO_FULL;
-+ irq_mask |= TRANSMIT_SERVICE_INT;
-+ if (!(registers[msp]->status & TX_FIFO_FULL)) {
-+ continue;
-+ }
-+ }
-+ if (rx_offset < rxbytes) {
-+ status_mask |= RX_FIFO_EMPTY;
-+ irq_mask |= RECEIVE_SERVICE_INT;
-+ if (!(registers[msp]->status & RX_FIFO_EMPTY)) {
-+ continue;
-+ }
-+ }
-+ registers[msp]->irq_mask |= irq_mask;
-+ status = wait_event_interruptible(wait[msp],
-+ !(registers[msp]->
-+ status &
-+ status_mask)
-+ && msp_io_error[msp]
-+ == 0);
-+ if (status) {
-+ return status;
-+ }
-+ }
-+ }
++ data = kzalloc(sizeof(struct fsmc_nomadik_info), GFP_KERNEL);
++ data->fsmc_reg = ioremap(res->start, res->end - res->start + 1);
++ platform_set_drvdata(pdev, data);
+
-+ return txbytes + rxbytes;
++ /*do platform specific fsmc init */
++ return (pdata->init());
+}
+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+
-+/**
-+ * msp_controller_cmd - To execute controller specific commands for MSP
-+ * @drv_data: SPI driver private data structure
-+ * @cmd: Command which is to be executed on the controller
-+ *
-+ *
++/*
++ * Clean up routine
+ */
-+static int msp_controller_cmd(struct driver_data *drv_data, int cmd)
++static int nomadik_fsmc_remove(struct platform_device *pdev)
+{
-+ int retval = 0;
-+ nmdk_dbg_ftrace();
-+ switch (cmd)
-+ {
-+ case DISABLE_CONTROLLER:
-+ {
-+ nmdk_dbg2(":::: DISABLE_CONTROLLER\n");
-+ writel((readl(MSP_GCR(drv_data->regs)) & (~(MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN ))), MSP_GCR(drv_data->regs));
-+ break;
-+ }
-+ case ENABLE_CONTROLLER:
-+ {
-+ nmdk_dbg2(":::: ENABLE_CONTROLLER\n");
-+ writel((readl(MSP_GCR(drv_data->regs)) | (MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN )), MSP_GCR(drv_data->regs));
-+ break;
-+ }
-+ case DISABLE_DMA:
-+ {
-+ nmdk_dbg2(":::: DISABLE_DMA\n");
-+ writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
-+ break;
-+ }
-+ case ENABLE_DMA:
-+ {
-+ nmdk_dbg2(":::: ENABLE_DMA\n");
-+ writel(drv_data->cur_chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
-+ break;
-+ }
-+ case DISABLE_ALL_INTERRUPT:
-+ {
-+ nmdk_dbg2(":::: DISABLE_ALL_INTERRUPT\n");
-+ writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+ break;
-+ }
-+ case ENABLE_ALL_INTERRUPT:
-+ {
-+ nmdk_dbg2(":::: ENABLE_ALL_INTERRUPT\n");
-+ writel( ENABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+ break;
-+ }
-+ case CLEAR_ALL_INTERRUPT:
-+ {
-+ nmdk_dbg2(":::: CLEAR_ALL_INTERRUPT\n");
-+ writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
-+ break;
-+ }
-+ case FLUSH_FIFO:
-+ {
-+ unsigned long limit = loops_per_jiffy << 1;
-+ nmdk_dbg2(":::: DATA FIFO is flushed\n");
-+ do {
-+ while( ! (readl(MSP_FLR(drv_data->regs)) & MSP_FLR_MASK_RFE))
-+ readl(MSP_DR(drv_data->regs));
-+ } while ((readl(MSP_FLR(drv_data->regs)) & (MSP_FLR_MASK_TBUSY | MSP_FLR_MASK_RBUSY)) && limit--);
-+ retval = limit;
-+ break;
-+ }
-+ case RESTORE_STATE:
-+ {
-+ struct chip_data *chip = drv_data->cur_chip;
-+ nmdk_dbg2(":::: RESTORE_STATE\n");
-+ writel(chip->regs.mspr.gcr, MSP_GCR(drv_data->regs));
-+ writel(chip->regs.mspr.tcf, MSP_TCF(drv_data->regs));
-+ writel(chip->regs.mspr.rcf, MSP_RCF(drv_data->regs));
-+ writel(chip->regs.mspr.srg, MSP_SRG(drv_data->regs));
-+ writel(chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
-+ writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+ writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
-+ break;
-+ }
-+ case LOAD_DEFAULT_CONFIG:
-+ {
-+ nmdk_dbg2(":::: LOAD_DEFAULT_CONFIG\n");
-+ writel(DEFAULT_MSP_REG_GCR, MSP_GCR(drv_data->regs));
-+ writel(DEFAULT_MSP_REG_TCF, MSP_TCF(drv_data->regs));
-+ writel(DEFAULT_MSP_REG_RCF, MSP_RCF(drv_data->regs));
-+ writel(DEFAULT_MSP_REG_SRG, MSP_SRG(drv_data->regs));
-+ writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
-+ writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+ writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
-+ break;
-+ }
-+ default:
-+ {
-+ nmdk_dbg2(":::: unknown command\n");
-+ retval = -1;
-+ break;
-+ }
-+ }
-+ return retval;
-+}
++ struct fsmc_nomadik_info *data = NULL;
+
-+void msp_u8_writer(struct driver_data *drv_data)
-+{
-+ u32 cur_write = 0;
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
-+ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+ return;
-+ writel((u32) (*(u8 *) (drv_data->tx)), MSP_DR(drv_data->regs));
-+ drv_data->tx += (drv_data->cur_chip->n_bytes);
-+ cur_write ++;
-+ if(cur_write == 8)
-+ return;
-+ }
-+}
-+void msp_u8_reader(struct driver_data *drv_data)
-+{
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
-+ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+ return;
-+ *(u8 *) (drv_data->rx) = (u8) readl(MSP_DR(drv_data->regs));
-+ drv_data->rx += (drv_data->cur_chip->n_bytes);
++ data = platform_get_drvdata(pdev);
++ if(data){
++ iounmap(data->fsmc_reg);
++ kfree(data);
+ }
++ return 0;
+}
-+void msp_u16_writer(struct driver_data *drv_data)
-+{
-+ u32 cur_write = 0;
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
+
-+ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+ return;
-+ writel((u32) (*(u16 *) (drv_data->tx)), MSP_DR(drv_data->regs));
-+ drv_data->tx += (drv_data->cur_chip->n_bytes);
-+ cur_write ++;
-+ if(cur_write == 8)
-+ return;
-+ }
-+}
-+void msp_u16_reader(struct driver_data *drv_data)
++#ifdef CONFIG_PM
++
++#define FSMC_REG_SIZE 0x78
++static char vect_fsmc[FSMC_REG_SIZE];
++int nomadik_fsmc_suspend(struct platform_device *pdev, pm_message_t state)
+{
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
-+ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+ return;
-+ *(u16 *) (drv_data->rx) = (u16) readl(MSP_DR(drv_data->regs));
-+ drv_data->rx += (drv_data->cur_chip->n_bytes);
-+ }
++ struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
++ printk("nomadik_fsmc_suspend: called......\n");
++ memcpy(vect_fsmc, data->fsmc_reg, FSMC_REG_SIZE);
++ return 0;
+}
+
-+void msp_u32_writer(struct driver_data *drv_data)
++int nomadik_fsmc_resume(struct platform_device *pdev)
+{
-+ u32 cur_write = 0;
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
++ struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
++ printk("nomadik_fsmc_resume: called......\n");
++ memcpy(data->fsmc_reg, vect_fsmc, FSMC_REG_SIZE);
+
-+ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+ return;
-+ /*Write Data to Data Register */
-+ writel(*(u32 *) (drv_data->tx), MSP_DR(drv_data->regs));
-+ drv_data->tx += (drv_data->cur_chip->n_bytes);
-+ cur_write ++;
-+ if(cur_write == 8)
-+ return;
-+ }
++ return 0;
+}
-+void msp_u32_reader(struct driver_data *drv_data)
++
++#else
++#define nomadik_fsmc_suspend NULL
++#define nomadik_fsmc_resume NULL
++
++#endif
++
++static struct platform_driver nomadik_fsmc_driver = {
++ .probe = nomadik_fsmc_probe,
++ .remove = nomadik_fsmc_remove,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "NOMADIK-FSMC",
++ },
++ .suspend = nomadik_fsmc_suspend,
++ .resume = nomadik_fsmc_resume,
++};
++
++static int __init nomadik_fsmc_init(void)
+{
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
-+ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+ return;
-+ *(u32 *) (drv_data->rx) = readl(MSP_DR(drv_data->regs));
-+ drv_data->rx += (drv_data->cur_chip->n_bytes);
-+ }
++ return platform_driver_register(&nomadik_fsmc_driver);
+}
+
-+static irqreturn_t nomadik_msp_interrupt_handler(int irq, void *dev_id)
++module_init(nomadik_fsmc_init);
++static void __exit nomadik_fsmc_exit(void)
+{
-+ struct driver_data *drv_data = (struct driver_data *)dev_id;
-+ struct spi_message *msg = drv_data->cur_msg;
-+ u32 irq_status = 0;
-+ u32 flag = 0;
-+ if (!msg) {
-+ dev_err(&drv_data->adev->dev,
-+ "bad message state in interrupt handler");
-+ /* Never fail */
-+ return IRQ_HANDLED;
-+ }
-+ /*Read the Interrupt Status Register */
-+ irq_status = readl(MSP_MIS(drv_data->regs));
++ platform_driver_unregister(&nomadik_fsmc_driver);
++ return;
++}
+
-+ if (irq_status) {
-+ if (irq_status & MSP_MIS_MASK_ROEMIS) { /*Overrun interrupt */
-+ /*Bail-out our Data has been corrupted */
-+ nmdk_dbg3(":::: Received ROR interrupt\n");
-+ drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
-+ drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
-+ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+ msg->state = ERROR_STATE;
-+ tasklet_schedule(&drv_data->pump_transfers);
-+ return IRQ_HANDLED;
-+ }
++module_exit(nomadik_fsmc_exit);
+
-+ drv_data->read(drv_data);
-+ drv_data->write(drv_data);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
++MODULE_DESCRIPTION("FSMC driver for Nomadik Platform");
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/gpio.c
+@@ -0,0 +1,916 @@
++/*
++ * linux/arch/arm/mach-nomadik/gpio.c
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#define GPIO_VER "2.1.0"
+
-+ if ((drv_data->tx == drv_data->tx_end) && (flag == 0)) {
-+ flag = 1;
-+ /*Disable Transmit interrupt */
-+ writel(readl(MSP_IMSC(drv_data->regs)) & (~MSP_IMSC_MASK_TXIM) & (~MSP_IMSC_MASK_TFOIM), (drv_data->regs + 0x14));
++#include <linux/kernel_stat.h>
++#include <linux/smp.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/signal.h>
++#include <linux/amba/bus.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/interrupt.h>
++#include <asm/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/debug.h>
++
++#define GPIO_NAME "GPIO"
++
++#ifndef GPIO_DEBUG
++#define GPIO_DEBUG 0
++#endif
++
++#define NMDK_DEBUG GPIO_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX GPIO_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++const char *gpio_block_name[4] = {
++ "GPIO_Block0", "GPIO_Block1", "GPIO_Block2", "GPIO_Block3",
++};
++
++static spinlock_t altfun_lock = SPIN_LOCK_UNLOCKED;
++static spinlock_t pinconf_lock = SPIN_LOCK_UNLOCKED;
++static struct gpio_soc *socdat = NULL; /*soc specific data ptr */
++extern struct irq_desc irq_desc[]; /* maintain interrupt info */
++
++#define CHK_VALID_CALL if (! socdat) { \
++ nmdk_error("called %s before initilization", __FUNCTION__); \
++ return(-EINVAL); \
+ }
-+ /*Clearing any Transmit underrun error. overrun already handled*/
-+ drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
+
-+ if (drv_data->rx == drv_data->rx_end) {
-+ drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
-+ drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
-+ nmdk_dbg3(":::: Interrupt transfer Completed...\n");
-+ /* Update total bytes transfered */
-+ msg->actual_length += drv_data->cur_transfer->len;
-+ if (drv_data->cur_transfer->cs_change)
-+ drv_data->cur_chip->
-+ cs_control(SPI_CHIP_DESELECT);
-+ /* Move to next transfer */
-+ msg->state = next_transfer(drv_data);
-+ tasklet_schedule(&drv_data->pump_transfers);
-+ return IRQ_HANDLED;
++#define CHK_VALID_PIN(pin) if (irq_desc[IRQNO_GPIO(pin)].action) {\
++ nmdk_error("%s failed, gpio%d used by irq %d", __FUNCTION__, pin , IRQNO_GPIO(pin));\
++ return -EINVAL;\
+ }
-+ }
-+ return IRQ_HANDLED;
-+}
+
-+static int verify_msp_controller_parameters(struct nmdk_spi_config_chip *chip_info)
++static char *nomadik_gpio_owner(gpio_pin pin_id)
+{
-+ nmdk_dbg_ftrace();
-+ /*FIXME: check clock params*/
-+ if ((chip_info->lbm != LOOPBACK_ENABLED)
-+ && (chip_info->lbm != LOOPBACK_DISABLED)) {
-+ nmdk_dbg(":::: Loopback Mode is configured incorrectly\n");
-+ return -1;
-+ }
-+ if (chip_info->iface != SPI_INTERFACE_MOTOROLA_SPI){
-+ nmdk_dbg(":::: Interface is configured incorrectly. This controller supports only MOTOROLA SPI\n");
-+ return -1;
-+ }
-+ if ((chip_info->hierarchy != SPI_MASTER)
-+ && (chip_info->hierarchy != SPI_SLAVE)) {
-+ nmdk_dbg(":::: hierarchy is configured incorrectly\n");
-+ return -1;
-+ }
-+ if ((chip_info->endian_rx != SPI_FIFO_MSB)
-+ && (chip_info->endian_rx != SPI_FIFO_LSB)) {
-+ nmdk_dbg(":::: Rx FIFO endianess is configured incorrectly\n");
-+ return -1;
-+ }
-+ if ((chip_info->endian_tx != SPI_FIFO_MSB)
-+ && (chip_info->endian_tx != SPI_FIFO_LSB)) {
-+ nmdk_dbg(":::: Tx FIFO endianess is configured incorrectly\n");
-+ return -1;
++ if (irq_desc[IRQNO_GPIO(pin_id)].action) {
++ return (char *)irq_desc[IRQNO_GPIO(pin_id)].action->name;
+ }
-+ if (((chip_info->controller).msp.data_size < MSP_DATA_BITS_8) || ((chip_info->controller).msp.data_size > MSP_DATA_BITS_32)) {
-+ nmdk_dbg(":::: MSP DATA Size is configured incorrectly\n");
-+ return -1;
++ if (irq_desc[IRQNO_GPIO(pin_id)].chip_data) {
++ return (char *)irq_desc[IRQNO_GPIO(pin_id)].chip_data;
+ }
-+ if ((chip_info->com_mode != INTERRUPT_TRANSFER)
-+ && (chip_info->com_mode != DMA_TRANSFER)
-+ && (chip_info->com_mode != POLLING_TRANSFER)) {
-+ nmdk_dbg(":::: Communication mode is configured incorrectly\n");
++ return (0);
++}
++
++/**
++ * nomadik_gpio_chkwr_permission - checks pin permission for write operation
++ */
++static int nomadik_gpio_chkwr_permission(gpio_pin pin_id, char *dev_name)
++{
++ char *pin_owner = nomadik_gpio_owner(pin_id);
++ if (!pin_owner) {
++ nmdk_error("pin %d not configured", pin_id);
+ return -1;
+ }
-+ if (chip_info->iface == SPI_INTERFACE_MOTOROLA_SPI) {
-+ if (((chip_info->proto_params).moto.clk_phase != SPI_CLK_ZERO_CYCLE_DELAY)
-+ && ((chip_info->proto_params).moto.clk_phase != SPI_CLK_HALF_CYCLE_DELAY)) {
-+ nmdk_dbg(":::: Clock Phase is configured incorrectly\n");
-+ return -1;
-+ }
-+ if (((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_LOW)
-+ && ((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_HIGH)) {
-+ nmdk_dbg(":::: Clock Polarity is configured incorrectly\n");
++ if (pin_owner != dev_name)
++ if (!strcmp(pin_owner, dev_name)) {
++ nmdk_error("pin %d not owned by %s", pin_id, dev_name);
+ return -1;
-+ }
+ }
-+ if (chip_info->cs_control == NULL) {
-+ nmdk_dbg("::::Chip Select Function is NULL for this chip\n");
-+ chip_info->cs_control = null_cs_control;
++ if (irq_desc[IRQNO_GPIO(pin_id)].action) {
++ nmdk_error("pin %d used as irq cannot be written", pin_id);
++ return -1;
+ }
+ return 0;
+}
+
-+/**
-+ * nomadik_msp_setup - setup function registered to SPI master framework
-+ * @spi: spi device which is requesting setup
-+ *
-+ * This function is registered to the SPI framework for this SPI master
-+ * controller. If it is the first time when setup is called by this device
-+ * , this function will initialize the runtime state for this chip and save
-+ * the same in the device structure. Else it will update the runtime info
-+ * with the updated chip info.
++/*
++ * Static Function declarations
+ */
-+
-+static int nomadik_msp_setup(struct spi_device *spi)
++static gpio_error gpio_setpinconfig(gpio_pin pin_id, gpio_config * config)
+{
-+ struct nmdk_spi_config_chip *chip_info;
-+ struct chip_data *chip;
-+ struct spi_master *master;
-+ int status = 0;
-+ u16 sckdiv = 0;
-+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++ unsigned long flags;
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++ gpio_error gpio_error = GPIO_OK;
++
+ nmdk_dbg_ftrace();
-+ master = drv_data->master;
++ spin_lock_irqsave(&pinconf_lock, flags);
++ if (config->dev_name)
++ irq_desc[IRQNO_GPIO(pin_id)].chip_data = config->dev_name;
++ else
++ irq_desc[IRQNO_GPIO(pin_id)].chip_data = "unknown";
++ spin_unlock_irqrestore(&pinconf_lock, flags);
+
-+ switch(master->bus_num) {
-+ case MSP_0_CONTROLLER:
-+ if((drv_data->flag_msp0->user != MSP_NO_USER) && (drv_data->flag_msp0->user != MSP_USER_SPI)){
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP0 already in use in %d mode", drv_data->flag_msp0->user);
-+ }
-+ else {
-+ down(&drv_data->flag_msp0->lock);
-+ drv_data->flag_msp0->user = MSP_USER_SPI;
-+ up(&drv_data->flag_msp0->lock);
-+ nmdk_dbg("Flag set to MSP_USER_SPI for MSP0\n");
-+ }
++ switch (config->mode) {
++ case GPIO_ALTF_A:
++ p_gpio_register->gpio_afsa |= mask;
++ p_gpio_register->gpio_afsb &= ~mask;
++ break;
++ case GPIO_ALTF_B:
++ p_gpio_register->gpio_afsa &= ~mask;
++ p_gpio_register->gpio_afsb |= mask;
++ break;
++ case GPIO_ALTF_C:
++ p_gpio_register->gpio_afsa |= mask;
++ p_gpio_register->gpio_afsb |= mask;
++ break;
++ case GPIO_MODE_SOFTWARE:
++ p_gpio_register->gpio_afsa &= ~mask;
++ p_gpio_register->gpio_afsb &= ~mask;
++
++ switch (config->direction) {
++ case GPIO_DIR_INPUT:
++ p_gpio_register->gpio_dirc = mask;
+ break;
-+ case MSP_1_CONTROLLER:
-+ if((drv_data->flag_msp1->user != MSP_NO_USER) && (drv_data->flag_msp1->user != MSP_USER_SPI)){
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP1 already in use in %d mode", drv_data->flag_msp1->user);
-+ }
-+ else {
-+ down(&drv_data->flag_msp1->lock);
-+ drv_data->flag_msp1->user = MSP_USER_SPI;
-+ up(&drv_data->flag_msp1->lock);
-+ nmdk_dbg("Flag set to MSP_USER_SPI for MSP1\n");
-+ }
++ case GPIO_DIR_OUTPUT:
++ p_gpio_register->gpio_dirs = mask;
+ break;
-+ case MSP_2_CONTROLLER:
-+ if((drv_data->flag_msp2->user != MSP_NO_USER) && (drv_data->flag_msp2->user != MSP_USER_SPI)){
-+ status = -EINVAL;
-+ printk(KERN_ERR "MSP2 already in use in %d mode", drv_data->flag_msp2->user);
-+ }
-+ else {
-+ down(&drv_data->flag_msp2->lock);
-+ drv_data->flag_msp2->user = MSP_USER_SPI;
-+ up(&drv_data->flag_msp2->lock);
-+ nmdk_dbg("Flag set to MSP_USER_SPI for MSP2\n");
-+ }
++ case GPIO_DIR_LEAVE_UNCHANGED:
+ break;
-+ }
-+ if(status)
-+ return status;
++ default:
++ return (GPIO_INVALID_PARAMETER);
++ }
+
-+ status = nomadik_gpio_altfuncenable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
-+ if (status < 0) {
-+ dev_err(&drv_data->adev->dev, "probe - unable to set GPIO Altfunc, %d\n", drv_data->master_info->gpio_alt_func);
-+ status = -ENODEV;
-+ goto err_out;
++ if (socdat->dbounce)
++ gpio_error =
++ socdat->dbounce(p_gpio_register, mask,
++ config->debounce,
++ config->debounce_time);
++ break;
++ case GPIO_MODE_LEAVE_UNCHANGED:
++ break;
++ default:
++ return (GPIO_INVALID_PARAMETER);
+ }
++ return (gpio_error);
++}
+
-+ status = request_irq(drv_data->adev->irq[0], nomadik_msp_interrupt_handler, 0, drv_data->master_info->device_name , drv_data);
-+ if (status < 0) {
-+ dev_err(&drv_data->adev->dev, "probe - cannot get IRQ (%d)\n", status);
-+ goto err_altfunc_enable;
++static gpio_error gpio_resetgpiopin(gpio_pin pin_id, char *dev_name)
++{
++ unsigned long flags;
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++ char *pin_dev_name;
++ gpio_error gpio_error = GPIO_OK;
++
++ nmdk_dbg_ftrace();
++ pin_dev_name = nomadik_gpio_owner(pin_id);
++ if (!pin_dev_name)
++ return 0;
++ if (strcmp(dev_name, pin_dev_name)) {
++ nmdk_error("Unable to free pin%d Current Owner is %s", pin_id,
++ pin_dev_name);
++ return (-1);
+ }
++ p_gpio_register->gpio_afsa &= ~mask;
++ p_gpio_register->gpio_afsb &= ~mask; /*software mode*/
++ p_gpio_register->gpio_dirc = mask; /*input dir*/
++ if (socdat->dbounce) /*disalbe debounce*/
++ gpio_error =
++ socdat->dbounce(p_gpio_register, mask,
++ GPIO_DEBOUNCE_DISABLE,
++ (gpio_debounce_time)NULL);
++ /* mark pin is freed */
+
-+ /* Get controller data */
-+ chip_info = spi->controller_data;
-+ /* Get controller_state */
-+ chip = spi_get_ctldata(spi);
-+ if (chip == NULL) {
-+ chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
-+ if (!chip) {
-+ dev_err(&spi->dev,
-+ "setup - cannot allocate controller state");
-+ goto err_request_irq;
-+ }
-+ chip->chip_id = spi->chip_select;
++ spin_lock_irqsave(&pinconf_lock, flags);
++ irq_desc[IRQNO_GPIO(pin_id)].chip_data = NULL;
++ spin_unlock_irqrestore(&pinconf_lock, flags);
++ if (irq_desc[IRQNO_GPIO(pin_id)].action)
++ irq_desc[IRQNO_GPIO(pin_id)].action->name = NULL;
++ return (gpio_error);
++}
+
-+ nmdk_dbg(":::: chip Id for this client = %d\n", chip->chip_id);
-+ nmdk_dbg(":::: Allocated Memory for controller's runtime state\n");
++gpio_config altfun_pinconfig;
++static gpio_error gpio_altfunction(gpio_alt_function alt_func,
++ int which_altfunc, char *dev_name)
++{
++ struct gpio_altfun_data *altfun_table = socdat->altfun_tbl;
++ int max_altfun = socdat->sz_altfun_tbl;
++ int i, j, start, end;
++ unsigned long flags;
++ u8 check_pins = 1; /*first check availability of all gpio pins */
++ gpio_error error = -1;
+
-+ if (chip_info == NULL) {
-+ /* spi_board_info.controller_data not is supplied */
-+ chip_info =
-+ kzalloc(sizeof(struct nmdk_spi_config_chip), GFP_KERNEL);
-+ if (!chip_info) {
-+ dev_err(&spi->dev,
-+ "setup - cannot allocate controller data");
-+ status = -ENOMEM;
-+ goto err_first_setup;
++ nmdk_dbg_ftrace();
++ spin_lock_irqsave(&altfun_lock, flags);
++ for (i = 0; i < max_altfun; i++) {
++ if (altfun_table[i].altfun != alt_func)
++ continue;
++ start = altfun_table[i].start;
++ end = altfun_table[i].end;
++ if (start > end) {
++ j = start;
++ start = end;
++ end = j;
++ }
++ if (end > GPIO_TOTAL_PINS) {
++ nmdk_error("range upto pin%d not suported", end);
++ error = GPIO_INVALID_PARAMETER;
++ goto exit_altfunc;
++ }
++ for (j = start; j <= end; j++) {
++ if (check_pins) {
++ if (nomadik_gpio_owner(j) &&
++ (which_altfunc != GPIO_ALTF_DISABLE)) {
++ nmdk_error("pin%d not free", j);
++ error = -1;
++ goto exit_altfunc;
++ }
++ if (!nomadik_gpio_owner(j) &&
++ (which_altfunc == GPIO_ALTF_DISABLE)) {
++ nmdk_error
++ ("Trying to disable free pin%d", j);
++ error = -1;
++ goto exit_altfunc;
++ }
++ } else {
++ if (which_altfunc == GPIO_ALTF_FIND) {
++ altfun_pinconfig.mode =
++ altfun_table[i].type;
++ } else {
++ altfun_pinconfig.mode = which_altfunc;
++ }
++ altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
++ altfun_pinconfig.debounce =
++ GPIO_DEBOUNCE_DISABLE;
++ altfun_pinconfig.dev_name = dev_name;
++
++ if (which_altfunc != GPIO_ALTF_DISABLE) {
++ error =
++ gpio_setpinconfig(j,
++ &altfun_pinconfig);
++ } else {
++ error = gpio_resetgpiopin(j, dev_name);
++ }
++ if (!error)
++ continue;
++ nmdk_error
++ ("GPIO %d configuration failure (nmdk_error:%d)",
++ j, error);
++ error = GPIO_INVALID_PARAMETER;
++ goto exit_altfunc;
+ }
-+ nmdk_dbg(":::: Allocated Memory for controller data\n");
++ }
++ if (altfun_table[i].cont == 0) {
++ /*schedule to configure if check sucessfull */
++ if (check_pins) {
++ check_pins = 0;
++ i = -1;
++ } else {
++ error = 0;
++ goto exit_altfunc;
++ }
++ }
++ }
++ exit_altfunc:
++ spin_unlock_irqrestore(&altfun_lock, flags);
++ return (error);
++}
+
-+ /* FIXME: Set controller data default value for MSP*/
-+ chip_info->lbm = LOOPBACK_DISABLED;
-+ chip_info->com_mode = POLLING_TRANSFER;
-+ chip_info->iface = SPI_INTERFACE_MOTOROLA_SPI;
-+ chip_info->hierarchy = SPI_MASTER;
-+ chip_info->endian_tx = SPI_FIFO_LSB;
-+ chip_info->endian_rx = SPI_FIFO_LSB;
-+ (chip_info->controller).msp.data_size = MSP_DATA_BITS_32;
++/**
++ * exported functions for other drives
++ */
+
-+ if(spi->max_speed_hz != 0)
-+ chip_info->freq = spi->max_speed_hz;
-+ else
-+ chip_info->freq = 48000;
++/*
++ * Get gpio list for /proc/gpio
++ */
++int get_gpio_list(char *buf)
++{
++ struct gpio_register *p_gpio_register;
++ uint32 mask;
++ char *p = buf;
++ char *gpiofunc;
++ char *gpio_client;
++ int i;
+
-+ (chip_info->proto_params).moto.clk_phase = SPI_CLK_HALF_CYCLE_DELAY;
-+ (chip_info->proto_params).moto.clk_pol = SPI_CLK_POL_IDLE_LOW;
-+ chip_info->cs_control = null_cs_control;
++ CHK_VALID_CALL;
++ p += sprintf(p, "Pin: %s\t%s\n", "mode", "client");
++ for (i = 0; i < GPIO_TOTAL_PINS; i++) {
++ gpio_client = nomadik_gpio_owner(i);
++ if (gpio_client) {
++ p_gpio_register = (struct gpio_register *)
++ get_irq_chip_data(GPIO_PIN2BLKIRQ(i));
++ mask = 1UL << (i % GPIO_PINS_PER_BLOCK);
++ if (irq_desc[IRQNO_GPIO(i)].action)
++ gpiofunc = "Irq";
++ else if ((p_gpio_register->gpio_afsa & mask)
++ && (p_gpio_register->gpio_afsb & mask))
++ gpiofunc = "AltFun_C";
++ else if ((p_gpio_register->gpio_afsa & mask)
++ && !(p_gpio_register->gpio_afsb & mask))
++ gpiofunc = "AltFun_A";
++ else if (!(p_gpio_register->gpio_afsa & mask)
++ && (p_gpio_register->gpio_afsb & mask))
++ gpiofunc = "AltFun_B";
++ else
++ gpiofunc = "I/O";
++ p += sprintf(p, "%3d: %s\t%s\n", i,
++ gpiofunc, gpio_client);
+ }
+ }
++ return p - buf;
++}
+
-+ if(chip_info->freq == 0){
-+ /*Calculate Specific Freq.*/
-+ if ( (MSP_INTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)
-+ || ( MSP_EXTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)){
-+ sckdiv = (chip_info->controller).msp.clk_freq.sckdiv;
++int nomadik_gpio_resetpinconfig(gpio_pin pin_id, char *dev_name)
++{
++ int error = 0;
+
-+ }else{
-+ status = -1;
-+ dev_err(&spi->dev, "setup - controller clock data is incorrect");
-+ goto err_config_params;
-+ }
-+ }else{
-+ /*Calculate Effective Freq.*/
-+ sckdiv =((DEFAULT_MSP_CLK) / (chip_info->freq)) - 1;
-+ if(sckdiv > MAX_SCKDIV){
-+ printk("SPI: Cannot set frequency less than 48Khz, setting lowest(48 Khz)\n");
-+ sckdiv = MAX_SCKDIV;
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ CHK_VALID_PIN(pin_id);
++
++ if (0 != nomadik_gpio_owner(pin_id))
++ error = gpio_resetgpiopin(pin_id, dev_name);
++ return (error);
++}
++
++int nomadik_gpio_setpinconfig(gpio_pin pin_id, gpio_config * pin_config)
++{
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ CHK_VALID_PIN(pin_id);
++ if (!irq_desc[IRQNO_GPIO(pin_id)].action) {
++ if (nomadik_gpio_owner(pin_id)) {
++ nmdk_error("pin%d not available.. aquired by %s client",
++ pin_id, nomadik_gpio_owner(pin_id));
++ return -1;
+ }
++ return (gpio_setpinconfig(pin_id, pin_config));
++ } else {
++ nmdk_error("Cannot set gpio%d used by irq %d", pin_id,
++ IRQNO_GPIO(pin_id));
++ return -1;
+ }
++ return 0;
++}
+
++int nomadik_gpio_writepin(gpio_pin pin_id, gpio_data value, char *dev_name)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
-+ status = verify_msp_controller_parameters(chip_info);
-+ if (status) {
-+ dev_err(&spi->dev, "setup - controller data is incorrect");
-+ goto err_config_params;
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ CHK_VALID_PIN(pin_id);
++ if (nomadik_gpio_chkwr_permission(pin_id, dev_name)) return -1;
++ switch (value) {
++ case GPIO_DATA_HIGH:
++ p_gpio_register->gpio_dats = mask;
++ break;
++ case GPIO_DATA_LOW:
++ p_gpio_register->gpio_datc = mask;
++ break;
++ default:
++ nmdk_error("Invalid value passed in %s", __FUNCTION__);
++ return GPIO_INVALID_PARAMETER;
+ }
++ return GPIO_OK;
++}
+
-+ /* Now set controller state based on controller data */
-+ chip->xfer_type = chip_info->com_mode;
-+ chip->cs_control = chip_info->cs_control;
-+
++int nomadik_gpio_readpin(gpio_pin pin_id, gpio_data * p_value)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
-+ /*FIXME: write all 8 & 16 bit functions*/
-+ if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_8) {
-+ nmdk_dbg(":::: Less than 8 bits per word....\n");
-+ chip->n_bytes = 1;
-+ chip->read = msp_u8_reader;
-+ chip->write = msp_u8_writer;
-+ } else if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_16) {
-+ nmdk_dbg(":::: Less than 16 bits per word....\n");
-+ chip->n_bytes = 2;
-+ chip->read = msp_u16_reader;
-+ chip->write = msp_u16_writer;
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ if ((p_gpio_register->gpio_dat & mask) != GPIO_ALL_ZERO) {
++ *p_value = GPIO_DATA_HIGH;
+ } else {
-+ nmdk_dbg(":::: Less than 32 bits per word....\n");
-+ chip->n_bytes = 4;
-+ chip->read = msp_u32_reader;
-+ chip->write = msp_u32_writer;
++ *p_value = GPIO_DATA_LOW;
+ }
++ return GPIO_OK;
++}
+
-+ /*Now Initialize all register settings reqd. for this chip */
++int nomadik_gpio_readblock(gpio_block_id block_id, uint32 * p_value,
++ uint32 mask)
++{
++ struct gpio_register *p_gpio_register;
+
-+ chip->regs.mspr.gcr = 0x0;
-+ chip->regs.mspr.tcf = 0x0;
-+ chip->regs.mspr.rcf = 0x0;
-+ chip->regs.mspr.srg = 0x0;
-+ chip->regs.mspr.dmacr = 0x0;
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
++ return GPIO_INVALID_PARAMETER;
+
-+ if ((chip_info->com_mode == DMA_TRANSFER)
-+ && ((drv_data->master_info)->enable_dma)) {
-+ chip->enable_dma = 1;
-+ chip->dma_info = kzalloc(sizeof(struct spi_dma_info), GFP_KERNEL);
-+ if(!chip->dma_info){
-+ nmdk_dbg("Could not allocate memory for dma info of chip_data\n");
-+ goto err_first_setup;
-+ }
-+ chip->dma_info->dma_xfer_type = chip_info->dma_xfer_type;
-+ nmdk_dbg(":::: DMA mode set in controller state\n");
-+ status = process_dma_info(chip_info, chip, (void *)drv_data);
-+ if (status < 0)
-+ goto err_config_params;
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_RDMAE, 0);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_TDMAE, 1);
++ if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
++ p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(block_id -
++ GPIO_BLOCK_32_BITS_0_TO_31
++ + IRQ_GPIO0);
++ *p_value = p_gpio_register->gpio_dat & (mask & GPIO_32BIT_MASK);
+
-+ /* find and request free dma chanel */
-+ chip->dma_info->rx_dmach = request_available_dma(&(chip->dma_info->rx_dma_info));
-+ if (chip->dma_info->rx_dmach < 0) {
-+ nmdk_dbg(":::: Rx pipe request Failed: %d\n", chip->dma_info->rx_dmach);
-+ goto err_rx_dmach_request;
++ } else {
++ p_gpio_register = (struct gpio_register *)
++ get_irq_chip_data((block_id -
++ GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
++ IRQ_GPIO0);
++ switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
++ case 0:
++ *p_value =
++ (p_gpio_register->gpio_dat & (mask & 0x0000ffff));
++ break;
++ case 1:
++ *p_value =
++ (p_gpio_register->
++ gpio_dat & (mask & 0x00ffff00)) >> GPIO_SHIFT8;
++ break;
++ case 2:
++ *p_value =
++ (p_gpio_register->
++ gpio_dat & (mask & 0xffff0000)) >> GPIO_SHIFT16;
++ break;
++ case 3:
++ *p_value =
++ (p_gpio_register->
++ gpio_dat & (mask & 0xff000000)) >> GPIO_SHIFT24;
++ p_gpio_register += SZ_4K; /* point next bank */
++ *p_value |=
++ (p_gpio_register->
++ gpio_dat & (mask & 0x000000ff)) << GPIO_SHIFT8;
++ break;
+ }
-+ nmdk_dbg(":::: Rx pipe Allocated = %d\n", chip->dma_info->rx_dmach);
++ }
++ return (GPIO_OK);
++}
+
-+ status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->rx_dmach),
-+ spi_dma_callback_handler, 0, 0,
-+ (void *)drv_data);
-+ if (status) {
-+ nmdk_error("Error requesting rx callback dmach intr handler %d", status);
-+ goto err_rx_clbk_request;
-+ }
++int nomadik_gpio_writeblock(gpio_block_id block_id, uint32 p_value, uint32 mask, char *dev_name)
++{
++ struct gpio_register *p_gpio_register;
++ int i, bankno, testmask;
+
-+ /* find and request free dma chanel */
-+ chip->dma_info->tx_dmach = request_available_dma(&(chip->dma_info->tx_dma_info));
-+ if (chip->dma_info->tx_dmach < 0) {
-+ nmdk_dbg(":::: Tx pipe request Failed: %d\n", status);
-+ goto err_tx_dmach_request;
-+ }
-+ nmdk_dbg(":::: Tx pipe Allocated = %d\n", chip->dma_info->tx_dmach);
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
++ return GPIO_INVALID_PARAMETER;
+
-+ status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->tx_dmach),
-+ spi_dma_callback_handler, 0, 0,
-+ (void *)drv_data);
-+ if (status) {
-+ nmdk_error("Error requesting callback dmach intr handler %d", status);
-+ goto err_tx_clbk_request;
++ if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
++ bankno = block_id * GPIO_PINS_PER_BLOCK;
++ testmask = 0x01;
++ for (i = bankno; i < (bankno + GPIO_PINS_PER_BLOCK); i++) {
++ if ((mask & testmask) &&
++ (!nomadik_gpio_chkwr_permission(i, dev_name))){
++ return -1;
++ }
++ testmask = 1UL << i;
+ }
-+ } else {
-+ chip->enable_dma = 0;
-+ nmdk_dbg(":::: DMA mode NOT set in controller state\n");
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_RDMAE, 0);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_TDMAE, 1);
-+ }
+
++ p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(block_id -
++ GPIO_BLOCK_32_BITS_0_TO_31
++ + IRQ_GPIO0);
++ p_gpio_register->gpio_datc =
++ ~(p_value & (mask & GPIO_32BIT_MASK));
++ p_gpio_register->gpio_dats = p_value & (mask & GPIO_32BIT_MASK);
+
-+ /**** GCR Reg Config *****/
-+
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RECEIVER_DISABLED, MSP_GCR_MASK_RXEN,0);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RX_FIFO_ENABLED, MSP_GCR_MASK_RFFEN,1);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMITTER_DISABLED, MSP_GCR_MASK_TXEN,8);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FIFO_ENABLED, MSP_GCR_MASK_TFFEN,9);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_POL_LOW, MSP_GCR_MASK_TFSPOL,10);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_INT, MSP_GCR_MASK_TFSSEL,11);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMIT_DATA_WITH_DELAY, MSP_GCR_MASK_TXDDL,15);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SAMPLE_RATE_GEN_ENABLE, MSP_GCR_MASK_SGEN,16);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_CLOCK_INTERNAL, MSP_GCR_MASK_SCKSEL,18);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_FRAME_GEN_ENABLE, MSP_GCR_MASK_FGEN,20);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, SPI_BURST_MODE_DISABLE, MSP_GCR_MASK_SPIBME,23);
-+
++ } else {
++ bankno = (block_id - GPIO_BLOCK_16_BITS_0_TO_15) * 8;
++ testmask = 0x01;
++ for (i = bankno; i < (bankno + (GPIO_PINS_PER_BLOCK / 2)); i++) {
++ if ((mask & testmask) &&
++ (!nomadik_gpio_chkwr_permission(i, dev_name))){
++ return -1;
++ }
++ testmask = 1UL << i;
++ }
++ p_gpio_register = (struct gpio_register *)
++ get_irq_chip_data((block_id -
++ GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
++ IRQ_GPIO0);
++ switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
++ case 0:
++ p_gpio_register->gpio_datc =
++ ~(p_value & (mask & 0x0000ffff));
++ p_gpio_register->gpio_dats =
++ p_value & (mask & 0x0000ffff);
++ break;
++ case 1:
++ p_gpio_register->gpio_datc =
++ ~(((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
++ p_gpio_register->gpio_dats =
++ (((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
++ break;
++ case 2:
++ p_gpio_register->gpio_datc =
++ ~(((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
++ p_gpio_register->gpio_dats =
++ (((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
++ break;
++ case 3:
++ p_gpio_register->gpio_datc =
++ ~(((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
++ p_gpio_register->gpio_dats =
++ (((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
++ p_gpio_register += SZ_4K; /* point next bank */
++ p_gpio_register->gpio_datc =
++ ~(p_value & (mask & 0x000000ff));
++ p_gpio_register->gpio_dats =
++ p_value & (mask & 0x000000ff);
++ break;
++ }
++ }
++ return (GPIO_OK);
++}
+
-+ if(chip_info->lbm == LOOPBACK_ENABLED)
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_ENABLED, MSP_GCR_MASK_LBM, 7);
-+ else
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_DISABLED, MSP_GCR_MASK_LBM, 7);
++int nomadik_gpio_altfuncenable(gpio_alt_function altfunc, char *dev_name)
++{
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
++}
+
++int nomadik_gpio_altfuncdisable(gpio_alt_function altfunc, char *dev_name)
++{
++ nmdk_dbg_ftrace();
++ CHK_VALID_CALL;
++ return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
++}
+
-+ if(chip_info->hierarchy == SPI_MASTER)
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_MASTER, MSP_GCR_MASK_TCKSEL, 14);
-+ else
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_SLAVE, MSP_GCR_MASK_TCKSEL, 14);
++EXPORT_SYMBOL(nomadik_gpio_setpinconfig);
++EXPORT_SYMBOL(nomadik_gpio_resetpinconfig);
++EXPORT_SYMBOL(nomadik_gpio_writepin);
++EXPORT_SYMBOL(nomadik_gpio_readpin);
++EXPORT_SYMBOL(nomadik_gpio_readblock);
++EXPORT_SYMBOL(nomadik_gpio_writeblock);
++EXPORT_SYMBOL(nomadik_gpio_altfuncenable);
++EXPORT_SYMBOL(nomadik_gpio_altfuncdisable);
+
++/**
++ * Interrupt handling functions
++ */
++static void nomadik_gpio_intrenable(struct gpio_register *p_gpio_register,
++ uint32 mask, uint32 type)
++{
++ if (socdat->irqen) {
++ socdat->irqen(p_gpio_register, mask, type);
++ } else {
++ nmdk_error("irqen SOC specific function not configured");
++ }
++}
+
-+ if(chip_info->proto_params.moto.clk_phase == SPI_CLK_ZERO_CYCLE_DELAY)
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_ZERO_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
++static void nomadik_gpio_intrdisable(struct gpio_register *p_gpio_register,
++ uint32 mask)
++{
++ if (socdat->irqdis)
++ socdat->irqdis(p_gpio_register, mask);
++ else {
++ nmdk_error("irqdis SOC specific function not configured");
++ }
++}
++/**
++ * @flag if 1 means enable, 0 means disable
++ */
++int nomadik_gpio_wakeupconfig(unsigned int irq, unsigned int flag)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
++ if (flag)
++ p_gpio_register->gpio_fwimsc |= mask;
+ else
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_HALF_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
++ p_gpio_register->gpio_fwimsc &= (~mask);
++ return 0;
++}
++void nomadik_gpio_slpmreg_config(gpio_pin pin_id)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++ uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++ p_gpio_register->gpio_slpm |= mask;
++}
+
-+ if(chip_info->proto_params.moto.clk_pol == SPI_CLK_POL_IDLE_HIGH)
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_HIGH, MSP_GCR_MASK_TCKPOL,13);
-+ else
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_LOW, MSP_GCR_MASK_TCKPOL,13);
++static void nomadik_gpio_mask(unsigned int irq)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
+
++ nmdk_dbg_ftrace();
++ nomadik_gpio_intrdisable(p_gpio_register, mask);
++}
+
-+ /**** RCF Reg Config *****/
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_IGNORE_RX_FRAME_SYNC_PULSE, MSP_RCF_MASK_RFSIG, 15);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_1BIT_DATA_DELAY, MSP_RCF_MASK_RDDLY, 13);
-+ if(chip_info->endian_rx == SPI_FIFO_LSB)
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_LSB , MSP_RCF_MASK_RENDN, 12);
-+ else
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_MSB , MSP_RCF_MASK_RENDN, 12);
++static void nomadik_gpio_unmask(unsigned int irq)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
+
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, chip_info->controller.msp.data_size , MSP_RCF_MASK_RP1ELEN, 0);
++ nmdk_dbg_ftrace();
++ if (!irq_desc[irq].handler_data) {
++ nmdk_info
++ ("for irq%d, configuruing default type as rising edge",
++ irq);
++ irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
++ }
++ nomadik_gpio_intrenable(p_gpio_register, mask,
++ (uint32) irq_desc[irq].handler_data);
++}
+
-+ /**** TCF Reg Config *****/
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_IGNORE_TX_FRAME_SYNC_PULSE, MSP_TCF_MASK_TFSIG, 15);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_1BIT_DATA_DELAY, MSP_TCF_MASK_TDDLY, 13);
-+ if(chip_info->endian_rx == SPI_FIFO_LSB)
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_LSB , MSP_TCF_MASK_TENDN, 12);
-+ else
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_MSB , MSP_TCF_MASK_TENDN, 12);
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, chip_info->controller.msp.data_size , MSP_TCF_MASK_TP1ELEN, 0);
++static void nomadik_gpio_intrack(unsigned int irq)
++{
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
+
-+ /**** SRG Reg Config *****/
-+ SPI_REG_WRITE_BITS(chip->regs.mspr.srg, sckdiv , MSP_SRG_MASK_SCKDIV , 0);
++ nmdk_dbg_ftrace();
++ p_gpio_register->gpio_ic = mask;
++}
+
-+ /* Save controller_state */
-+ spi_set_ctldata(spi, chip);
-+ return status;
++/*
++ * callback function for gpio specific set_irq_type sys call
++ * This function will be called in the context of request_irq also
++ */
++static int nomadik_gpio_intrsettype(unsigned int irq, unsigned int type)
++{
++ gpio_config settype_config;
++ char *client_name = nomadik_gpio_owner(GPIO_PIN_FOR_IRQ(irq));
++ int ret;
+
-+err_tx_clbk_request:
-+ if (chip->dma_info->tx_dmach != -1) {
-+ free_dma(chip->dma_info->tx_dmach);
++ nmdk_dbg_ftrace();
++ type&=SA_TRIGGER_MASK;
++ /* mistake proofing for invalid entry incase if you try to configure
++ * gpiopin interrupt for priority/fiq
++ */
++ if ( (type == SA_TRIGGER_MASK) ||
++ (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_RISING)) ||
++ (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_FALLING)) ||
++ (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH))) {
++ nmdk_error("Invalid IRQ type requested for irq%d", irq);
++ return -1;
+ }
-+err_tx_dmach_request:
-+err_rx_clbk_request:
-+ if (chip->dma_info->rx_dmach != -1) {
-+ free_dma(chip->dma_info->rx_dmach);
++ if (!irq_desc[irq].action) {
++ nmdk_error("Trying to set type for unrequested irq%d", irq);
+ }
-+err_rx_dmach_request:
-+ chip->dma_info->tx_dmach = -1;
-+ chip->dma_info->rx_dmach = -1;
-+err_config_params:
-+err_first_setup:
-+ if(chip->dma_info)
-+ kfree(chip->dma_info);
-+ kfree(chip);
-+err_request_irq:
-+ free_irq(drv_data->adev->irq[0], drv_data);
-+err_altfunc_enable:
-+ nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
-+err_out:
-+ switch(master->bus_num) {
-+ case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user == MSP_USER_SPI) {
-+ down(&drv_data->flag_msp0->lock);
-+ drv_data->flag_msp0->user = MSP_NO_USER;
-+ up(&drv_data->flag_msp0->lock);
-+ nmdk_dbg("Flag cleanup for MSP0\n");
-+ }
-+ else {
-+ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp0->user);
-+ status = -EFAULT;
-+ }
-+ break;
-+ case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user == MSP_USER_SPI) {
-+ down(&drv_data->flag_msp1->lock);
-+ drv_data->flag_msp1->user = MSP_NO_USER;
-+ up(&drv_data->flag_msp1->lock);
-+ nmdk_dbg("Flag cleanup for MSP1\n");
-+ }
-+ else {
-+ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
-+ status = -EFAULT;
-+ }
-+ break;
-+ case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user == MSP_USER_SPI) {
-+ down(&drv_data->flag_msp2->lock);
-+ drv_data->flag_msp2->user = MSP_NO_USER;
-+ up(&drv_data->flag_msp2->lock);
-+ nmdk_dbg("Flag cleanup for MSP2\n");
-+ }
-+ else {
-+ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
-+ status = -EFAULT;
-+ }
-+ break;
++ if (irq_desc[irq].handler_data) {
++ nmdk_info("irq %d type already set by %s", irq,
++ client_name);
++ return (0);
++ }
++ settype_config.mode = GPIO_MODE_SOFTWARE;
++ settype_config.direction = GPIO_DIR_INPUT;
++ settype_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
++ settype_config.dev_name = client_name;
++ ret = gpio_setpinconfig(GPIO_PIN_FOR_IRQ(irq), &settype_config);
++ if (ret < 0) {
++ nmdk_error("Error in setting irq %d (err %d)", irq, ret);
++ return (ret);
++ }
++ nmdk_dbg("set_irq_type =%d", type);
++ if (type) {
++ irq_desc[irq].handler_data = (void *)(type & SA_TRIGGER_MASK);
++ } else {
++ nmdk_info
++ ("%s Configuring default irq type to SA_TRIGGER_RISING",
++ __FUNCTION__);
++ irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
+ }
++ if ((SA_TRIGGER_RISING == (int)irq_desc[irq].handler_data) ||
++ (SA_TRIGGER_FALLING == (int)irq_desc[irq].handler_data))
++ irq_desc[irq].handle_irq = handle_edge_irq;
++ else if ((SA_TRIGGER_LOW == (int)irq_desc[irq].handler_data) ||
++ (SA_TRIGGER_HIGH == (int)irq_desc[irq].handler_data))
++ irq_desc[irq].handle_irq = handle_level_irq;
++ /* Standard api call set_irq_handler() cannot be used from
++ the contest of set_irq_type... deadlock occures */
+
-+ return status;
++ return (GPIO_OK);
+}
+
-+#endif
-+
-+
-+int msp_probe(struct amba_device *adev, void *data)
++/**
++ * callback function for enable_irq_wake and disable_irq_wake system calls
++ *
++ * @flag if 1 means enable, 0 means disable
++ */
++static int nomadik_gpio_intrwake(unsigned int irq, unsigned int flag)
+{
-+ int status = 0;
-+ struct device *dev;
-+ struct nmdk_spi_master_cntlr *platform_info;
++ struct gpio_register *p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++ uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
++ unsigned int type = (uint32) irq_desc[irq].handler_data;
+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+ struct spi_master *master;
-+ struct driver_data *drv_data = NULL; /*Data for this driver */
-+ struct resource *res;
-+ int irq;
-+#endif
-+ dev = &adev->dev;
-+ platform_info = (struct nmdk_spi_master_cntlr *)(dev->platform_data);
-+ if (platform_info == NULL) {
-+ dev_err(&adev->dev, "probe - no platform data supplied\n");
-+ status = -ENODEV;
-+ goto err_no_pdata;
++ if (socdat->irqwake) {
++ if (!type)
++ type = SA_TRIGGER_RISING;
++ if (!flag)
++ type = 0xff; /* to disable wakeup irq */
++ socdat->irqwake(p_gpio_register, mask, type);
++ } else {
++ nmdk_error("irqwake SOC specific function not configured");
++ return (-1);
+ }
++ return (0);
++}
+
-+ if(platform_info->id == MSP_0_CONTROLLER) {
-+ flag_msp0= kmalloc(sizeof(msp_flag), GFP_KERNEL);
-+ if(!flag_msp0) {
-+ status = -ENOMEM;
-+ printk(KERN_ERR "No mem available for MSP0 flag\n");
-+ goto err_msp0;
-+ }
-+ flag_msp0->user = MSP_NO_USER;
-+ init_MUTEX(&flag_msp0->lock);
-+ init_waitqueue_head(&wait[0]);
-+ nmdk_dbg("In msp_probe flag_msp0 is %d\n", flag_msp0->user);
-+ }
-+ if(platform_info->id == MSP_1_CONTROLLER) {
-+ flag_msp1= kmalloc(sizeof(msp_flag), GFP_KERNEL);
-+ if(!flag_msp1) {
-+ status = -ENOMEM;
-+ printk(KERN_ERR "No mem available for MSP1 flag\n");
-+ goto err_msp1;
-+ }
-+ flag_msp1->user = MSP_NO_USER;
-+ init_MUTEX(&flag_msp1->lock);
-+ init_waitqueue_head(&wait[1]);
-+ nmdk_dbg("In msp_probe flag_msp1 is %d\n", flag_msp1->user);
-+ }
-+ if(platform_info->id == MSP_2_CONTROLLER) {
-+ flag_msp2= kmalloc(sizeof(msp_flag), GFP_KERNEL);
-+ if(!flag_msp2) {
-+ status = -ENOMEM;
-+ printk(KERN_ERR "No mem available for MSP2 flag\n");
-+ goto err_msp2;
++struct irq_chip nomadik_gpio_chip = {
++ .ack = nomadik_gpio_intrack,
++ .mask = nomadik_gpio_mask,
++ .unmask = nomadik_gpio_unmask,
++ .set_type = nomadik_gpio_intrsettype,
++ .set_wake = nomadik_gpio_intrwake,
++};
++
++static void nomadik_gpio_intr_handler(u32 irq, struct irq_desc *desc)
++{
++ struct gpio_register *p_gpio_reg =
++ (struct gpio_register *)get_irq_chip_data(irq);
++ unsigned long mis = p_gpio_reg->gpio_mis;
++
++ nmdk_dbg2("%d intr desc %p", (irq - IRQ_GPIO0), desc);
++ irq = IRQNO_GPIO((irq - IRQ_GPIO0) * GPIO_PINS_PER_BLOCK);
++ desc = irq_desc + irq;
++ while (mis) {
++ if (mis & 1) {
++ nmdk_dbg2("handling irq %d", irq);
++ desc->handle_irq(irq, desc);
+ }
-+ flag_msp2->user = MSP_NO_USER;
-+ init_MUTEX(&flag_msp2->lock);
-+ init_waitqueue_head(&wait[2]);
-+ nmdk_dbg("In msp_probe flag_msp2 is %d\n", flag_msp2->user);
++ irq++;
++ desc++;
++ mis >>= 1;
+ }
++}
++
++static int nomadik_gpio_probe(struct amba_device *dev, void *id)
++{
++ int i, ret;
++ struct gpio_register *p_gpio_register;
++
+ nmdk_dbg_ftrace();
+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+ /* Allocate master with space for drv_data */
-+ master = spi_alloc_master(dev, sizeof(struct driver_data));
-+ if (master == NULL) {
-+ dev_err(&adev->dev, "probe - cannot alloc spi_master\n");
-+ status = -ENOMEM;
-+ goto err_no_mem;
++ socdat = dev->dev.platform_data;
++
++ if (!socdat) {
++ nmdk_error("platform_data struct for %s not initialized",
++ dev->dev.bus_id);
++ ret = -1;
++ goto out;
+ }
++ ret = amba_request_regions(dev, NULL);
++ if (ret)
++ goto out;
+
-+ drv_data = spi_master_get_devdata(master);
-+ drv_data->master = master;
-+ drv_data->master_info = platform_info;
-+ drv_data->adev = adev;
++ for (i = 0; i < (dev->irq[1] - dev->irq[0]); i++) {
++ set_irq_chip_data((i + dev->irq[0]),
++ (void *)ioremap((int)dev->res.start +
++ (i * SZ_4K), SZ_4K));
+
-+ drv_data->dma_ongoing = 0;
++ p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
+
-+ /*Fetch the Resources, using platform data */
++ if (!p_gpio_register) {
++ ret = -ENOMEM;
++ goto res_out;
++ }
+
-+ res = &(adev->res);
-+ if (res == NULL) {
-+ dev_err(&adev->dev, "probe - MEM resources not defined\n");
-+ status = -ENODEV;
-+ goto err_no_iores;
-+ }
-+ /*Get Hold of Device Register Area... */
-+ drv_data->regs = ioremap(res->start, (res->end - res->start));
-+ if (drv_data->regs == NULL) {
-+ status = -ENODEV;
-+ goto err_no_iores;
-+ }
-+ irq = adev->irq[0];
-+ if (irq <= 0) {
-+ status = -ENODEV;
-+ goto err_no_iores;
++ set_irq_chained_handler((i + dev->irq[0]),
++ nomadik_gpio_intr_handler);
+ }
+
-+ /*Set flag for MSPx*/
-+ switch(platform_info->id) {
-+ case MSP_0_CONTROLLER:
-+ drv_data->flag_msp0 = (spi_msp_user *)flag_msp0;
-+ break;
-+ case MSP_1_CONTROLLER:
-+ drv_data->flag_msp1 = (spi_msp_user *)flag_msp1;
-+ break;
-+ case MSP_2_CONTROLLER:
-+ drv_data->flag_msp2 = (spi_msp_user *)flag_msp2;
-+ break;
-+ default:
-+ dev_err(&adev->dev, "unknown controller Id %d\n", platform_info->id);
-+ status = -EINVAL;
-+ break;
++ for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
++ set_irq_chip(i, &nomadik_gpio_chip);
++ set_irq_handler(i, handle_level_irq);
++ set_irq_flags(i, IRQF_VALID);
++ set_irq_chip_data(i, NULL); /*clear gpio client name */
++ irq_desc[i].handler_data = NULL; /*clear gpio irq_type */
+ }
+
-+ if(status == -EINVAL)
-+ goto err_no_irqres;
++ nmdk_info("Module initialized Ver(" GPIO_VER ")");
++ return 0;
+
-+ nmdk_dbg(":::: MSP Controller = %d\n", platform_info->id);
-+ drv_data->execute_cmd = msp_controller_cmd;
-+ drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
-+ master->setup = nomadik_msp_setup;
++ res_out:
++ for (; 0 == i; i--) {
++ p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
+
-+ /*Required Info for an SPI controller */
-+ /*Bus Number Which has been Assigned to this SPI controller on this board */
-+ master->bus_num = (u16) platform_info->id;
-+ master->num_chipselect = platform_info->num_chipselect;
-+ master->cleanup = nomadik_spi_cleanup;
-+ master->transfer = nomadik_spi_transfer;
++ set_irq_handler((i + dev->irq[0]), handle_bad_irq);
++ if (p_gpio_register)
++ iounmap((void __iomem *)p_gpio_register);
++ set_irq_chip_data((i + dev->irq[0]), NULL);
+
-+ nmdk_dbg(":::: BUSNO: %d\n", master->bus_num);
-+ /* Initialize and start queue */
-+ status = init_queue(drv_data);
-+ if (status != 0) {
-+ dev_err(&adev->dev, "probe - problem initializing queue\n");
-+ goto err_init_queue;
+ }
-+ status = start_queue(drv_data);
-+ if (status != 0) {
-+ dev_err(&adev->dev, "probe - problem starting queue\n");
-+ goto err_start_queue;
++ amba_release_regions(dev);
++ out:
++ return (ret);
++}
++
++static int nomadik_gpio_remove(struct amba_device *dev)
++{
++ int i;
++
++ nmdk_dbg_ftrace();
++ for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
++ set_irq_chip(i, NULL);
++ set_irq_chip_data(i, NULL);
+ }
-+ /*Initialize tasklet for DMA transfer*/
-+ tasklet_init(&drv_data->spi_dma_tasklet, nomadik_spi_tasklet,
-+ (unsigned long)drv_data);
+
-+ /* Register with the SPI framework */
-+ platform_set_drvdata(adev, drv_data);
-+ status = spi_register_master(master);
-+ if (status != 0) {
-+ dev_err(&adev->dev, "probe - problem registering spi master\n");
-+ goto err_spi_register;
++ for (i = dev->irq[0]; i < dev->irq[1]; i++) {
++ set_irq_handler(i, handle_bad_irq);
++ iounmap((void __iomem *)get_irq_chip_data(i));
++ set_irq_chip_data(i, NULL);
+ }
-+ dev_dbg(dev, "probe succeded\n");
-+ nmdk_dbg(" Bus Number = %d, IRQ Line = %d, Virtual Addr: %x\n", master->bus_num, irq, (u32)(drv_data->regs) );
++ amba_release_regions(dev);
++ socdat = NULL;
++ nmdk_info("Module removed");
+ return 0;
-+#endif
-+ return status;
-+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+ err_init_queue:
-+ err_start_queue:
-+ err_spi_register:
-+ destroy_queue(drv_data);
-+ err_no_irqres:
-+ err_no_iores:
-+ spi_master_put(master);
-+ err_no_mem:
-+#endif
-+ if((flag_msp2) && (platform_info->id == MSP_2_CONTROLLER))
-+ kfree(flag_msp2);
-+ err_msp2:
-+ if((flag_msp1) && (platform_info->id == MSP_1_CONTROLLER))
-+ kfree(flag_msp1);
-+ err_msp1:
-+ if((flag_msp0) && (platform_info->id == MSP_0_CONTROLLER))
-+ kfree(flag_msp0);
-+ err_msp0:
-+ err_no_pdata:
-+ return status;
-+
+}
+
-+static int msp_remove(struct amba_device *adev)
++#if (defined CONFIG_PM && defined __STN_8815)
++static int nomadik_gpio_suspend(struct amba_device *dev, pm_message_t state)
+{
-+ struct driver_data *drv_data = platform_get_drvdata(adev);
-+ struct device *dev = &adev->dev;
-+ struct nmdk_spi_master_cntlr *platform_info;
-+ int irq;
-+ int status = 0;
-+ if (!drv_data)
-+ return 0;
-+
-+ platform_info = dev->platform_data;
++ unsigned int i;
++ struct gpio_register *p_gpio_register;
++ struct gpio_pm_context *gpio_pm;;
+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+ /* Remove the queue */
-+ status = destroy_queue(drv_data);
-+ if (status != 0) {
-+ dev_err(&adev->dev, "queue remove failed (%d)\n", status);
-+ return status;
++ nmdk_dbg_ftrace();
++ dev->dev.driver_data =
++ kmalloc(sizeof(struct gpio_pm_context) * GPIO_BLOCKS_COUNT,
++ GFP_KERNEL);
++ gpio_pm = (struct gpio_pm_context *)dev->dev.driver_data;
++ if (!gpio_pm) {
++ nmdk_error("Unable to alocate memory %s failed...",
++ __FUNCTION__);
+ }
-+ drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
-+
-+ irq = adev->irq[0];
-+ if (irq >= 0)
-+ free_irq(irq, drv_data);
-+
-+ /* Release map resources */
-+ iounmap(drv_data->regs);
-+ tasklet_disable(&drv_data->pump_transfers);
-+ tasklet_kill(&drv_data->spi_dma_tasklet);
-+ nomadik_gpio_altfuncdisable(platform_info->gpio_alt_func, platform_info->device_name);
++ for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
++ p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
++ gpio_pm[i].slpm = p_gpio_register->gpio_slpm;
++ gpio_pm[i].rwimsc = p_gpio_register->gpio_rwimsc;
++ gpio_pm[i].fwimsc = p_gpio_register->gpio_fwimsc;
++ gpio_pm[i].rimsc = p_gpio_register->gpio_rimsc;
++ gpio_pm[i].fimsc = p_gpio_register->gpio_fimsc;
++ }
++ return 0;
++}
+
-+ /* Disconnect from the SPI framework */
-+ spi_unregister_master(drv_data->master);
-+ spi_master_put(drv_data->master);
++static int nomadik_gpio_resume(struct amba_device *dev)
++{
++ unsigned int i;
++ struct gpio_register *p_gpio_register;
++ struct gpio_pm_context *gpio_pm =
++ (struct gpio_pm_context *)dev->dev.driver_data;
+
-+ /* Prevent double remove */
-+ platform_set_drvdata(adev, NULL);
-+ dev_dbg(&adev->dev, "remove succeded\n");
-+#endif
-+ if(platform_info->id == MSP_0_CONTROLLER) {
-+ if(flag_msp0)
-+ kfree(flag_msp0);
-+ else
-+ printk("MSP Error:why flag_msp0==NULL???");
-+ }
-+ if(platform_info->id == MSP_1_CONTROLLER) {
-+ if(flag_msp1)
-+ kfree(flag_msp1);
-+ else
-+ printk("MSP Error:why flag_msp1==NULL???");
-+ }
-+ if(platform_info->id == MSP_2_CONTROLLER) {
-+ if(flag_msp2)
-+ kfree(flag_msp2);
-+ else
-+ printk("MSP Error:why flag_msp2==NULL???");
++ nmdk_dbg_ftrace();
++ for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
++ p_gpio_register =
++ (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
++ p_gpio_register->gpio_slpm = gpio_pm[i].slpm;
++ p_gpio_register->gpio_rwimsc = gpio_pm[i].rwimsc;
++ p_gpio_register->gpio_fwimsc = gpio_pm[i].fwimsc;
++ p_gpio_register->gpio_rimsc = gpio_pm[i].rimsc;
++ p_gpio_register->gpio_fimsc = gpio_pm[i].fimsc;
+ }
-+
++ kfree(gpio_pm);
+ return 0;
+}
++#else
++#define nomadik_gpio_suspend NULL
++#define nomadik_gpio_resume NULL
++#endif
+
-+static struct amba_id msp_ids[] = {
++static struct amba_id nomadik_gpio_ids[] = {
+ {
-+ .id = MSP_PER_ID,
-+ .mask = MSP_PER_MASK,
++ .id = GPIO_PER_ID,
++ .mask = GPIO_PER_MASK,
+ },
+ {0, 0},
+};
+
-+static struct amba_driver msp_driver = {
++static struct amba_driver gpio_driver = {
+ .drv = {
-+ .name = "MSP",
++ .owner = THIS_MODULE,
++ .name = "gpio",
+ },
-+ .id_table = msp_ids,
-+ .probe = msp_probe,
-+ .remove = msp_remove
++ .probe = nomadik_gpio_probe,
++ .remove = nomadik_gpio_remove,
++ .suspend = nomadik_gpio_suspend,
++ .resume = nomadik_gpio_resume,
++ .id_table = nomadik_gpio_ids,
+};
+
-+EXPORT_SYMBOL(nomadik_msp_configure);
-+EXPORT_SYMBOL(nomadik_msp_send_data);
-+EXPORT_SYMBOL(nomadik_msp_receive_data);
-+EXPORT_SYMBOL(nomadik_msp_transceive_data);
-+EXPORT_SYMBOL(nomadik_msp_enable);
-+EXPORT_SYMBOL(nomadik_msp_disable);
-+EXPORT_SYMBOL(nomadik_msp_flush_input);
-+
-+static int __init nomadik_msp_mod_init(void)
++static int __init nomadik_gpio_init(void)
+{
-+ return amba_driver_register(&msp_driver);
++ return amba_driver_register(&gpio_driver);
+}
+
-+static void __exit nomadik_msp_exit(void)
++static void __exit nomadik_gpio_exit(void)
+{
-+ amba_driver_unregister(&msp_driver);
-+ return;
++ amba_driver_unregister(&gpio_driver);
+}
-+module_init(nomadik_msp_mod_init);
-+module_exit(nomadik_msp_exit);
+
-+MODULE_AUTHOR("STMicroelectronics Pvt Ltd");
-+MODULE_DESCRIPTION("NOMADIK MSP driver");
++EXPORT_SYMBOL(nomadik_gpio_intrsettype);
++EXPORT_SYMBOL(nomadik_gpio_mask);
++EXPORT_SYMBOL(nomadik_gpio_unmask);
++
++module_init(nomadik_gpio_init);
++module_exit(nomadik_gpio_exit);
++
++MODULE_AUTHOR("Prafulla WADASKAR <prafulla.wadaskar@st.com>");
++MODULE_DESCRIPTION("Nomadik GPIO Driver");
+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/msp.h ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.h
---- linux-2.6.20/arch/arm/mach-nomadik/msp.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.h 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,383 @@
-+/*linux/drivers/char/nomadik-msp.h
-+ *
-+ * Driver for Nomadik STN8810 MSP device. Note that this module MUST NOT
-+ * attempt to load before the i2c and gpio drivers are loaded.
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/irq.c
+@@ -0,0 +1,231 @@
++/*
++ * linux/arch/arm/mach-nomadik/irq.c
+ *
-+ * Copyright 2006 STMicroelectronics Pvt. Ltd.
++ * Copyright (C) STMicroelectronics
+ *
-+ * This program is free sofstware; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
+ *
++ * Author : Prafulla WADASKAR <prafulla.wadaskar@st.com>
++ * Reference : Documentation/arm/STM-Nomadik/irq_usrguide.txt
+ */
++#include <linux/kernel_stat.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/debug.h>
+
-+#ifndef NMDK_MSP_HEADER
-+#define NMDK_MSP_HEADER
++#define VIC_VER "2.0.0"
++#define VIC_NAME "VIC"
+
-+struct msp_register
-+{
-+ u32 fifo;
-+ u32 global_ctrl;
-+ u32 tx_config;
-+ u32 rx_config;
-+ u32 srg_ctrl;
-+ u32 status;
-+ u32 dma_ctrl;
-+ u32 reserved0;
-+ u32 irq_mask;
-+ u32 raw_irq_status;
-+ u32 masked_irq_status;
-+ u32 irq_clear;
-+ u32 multichannel_ctrl;
-+ u32 rx_compare_val;
-+ u32 rx_compare_mask;
-+ u32 reserved1;
-+ u32 tx_enable_ch0;
-+ u32 tx_enable_ch1;
-+ u32 tx_enable_ch2;
-+ u32 tx_enable_ch3;
-+ u32 reserved2[4];
-+ u32 rx_enable_ch0;
-+ u32 rx_enable_ch1;
-+ u32 rx_enable_ch2;
-+ u32 rx_enable_ch3;
-+ u32 reserved3[4];
-+ u32 test_ctrl;
-+ u32 integration_test_input;
-+ u32 integration_test_output;
-+ u32 test_data;
-+};
++#ifndef VIC_DEBUG
++#define VIC_DEBUG 0
++#endif
+
-+struct msp_context {
-+ u8 direction;
-+ u8 mode;
-+ u8 protocol;
-+ int frame_freq;
-+ int frame_size;
-+ enum msp_data_size requested_data_size;
-+ enum msp_data_size actual_data_size;
++#define NMDK_DEBUG VIC_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX VIC_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
+
-+ u32 rx_channel_0_enable;
-+ u32 rx_channel_1_enable;
-+ u32 rx_channel_2_enable;
-+ u32 rx_channel_3_enable;
-+ u32 tx_channel_0_enable;
-+ u32 tx_channel_1_enable;
-+ u32 tx_channel_2_enable;
-+ u32 tx_channel_3_enable;
-+ u32 multichannel_ctrl_reg;
-+ u32 rx_compare_mask_reg;
-+ u32 irq_mask_reg;
++struct vic_basic_registers {
++ u32 irqsr; /* IRQ Status*/
++ u32 fiqsr; /* FIQ Status*/
++ u32 ris; /* Raw Interrupt status*/
++ u32 isel; /* Interrupt select*/
++ u32 iens; /* Interrupt enable set*/
++ u32 ienc; /* Interrupt enable clear*/
++ u32 swisr; /* Software interrupt*/
++ u32 swicr; /* Software interrupt clear*/
++};
+
-+ u8 compression_mode;
-+ u8 expansion_mode;
-+ u8 coprocessor_mode;
-+ int msp_disable;
++struct vic_register {
++ struct vic_basic_registers bank[(MAXIRQNUM/32) +1];
++ u32 per; /* Protection enable*/
++#if defined(__STN_8815)
++ u32 reserved_1[(0x50 - 0x44) >> 2]; /* Reserved*/
++ u32 isr_var; /* ISR Vector address*/
++ u32 isr_dvar; /* ISR Default vector address*/
++ u32 reserved_2[(0x100 - 0x58) >> 2]; /* Reserved*/
++#elif defined(__STN_8810)
++ u32 reserved_1[(0x30 - 0x24) >> 2]; /* Reserved*/
++ u32 isr_var; /* ISR Vector address*/
++ u32 isr_dvar; /* ISR Default vector address*/
++ u32 reserved_2[(0x100 - 0x38) >> 2]; /* Reserved*/
++#endif
++ u32 var[VIC_VECTORED_IRQ_NUM]; /* Vector address 0-15*/
++ u32 reserved_3[(0x200 - 0x140) >> 2]; /* Reserved*/
++ u32 vcr[VIC_VECTORED_IRQ_NUM]; /* Vector control 0-15*/
++ u32 reserved_4[(0x300 - 0x240) >> 2]; /* Reserved*/
++ u32 itcr; /* Test Control register*/
++ u32 itip_1; /* Test input nVICIRQIN/nVICFIQIN*/
++ u32 itip_2; /* Test input VICVECADDRIN*/
++ u32 itop_1; /* Test output nVICIRQ/nVICFIQ*/
++ u32 itop_2; /* Test output VICVECADDROUT*/
++ u32 reserved_5[(0xFE0 - 0x314) >> 2]; /* Reserved*/
++ u32 periph_id_0; /* Peripheral id: bits 7:0*/
++ u32 periph_id_1; /* Peripheral id: bits 15:8*/
++ u32 periph_id_2; /* Peripheral id: bits 23:16*/
++ u32 periph_id_3; /* Peripheral id: bits 31:24*/
++ u32 pcell_id_0; /* PrimeCell id: bits 7:0*/
++ u32 pcell_id_1; /* PrimeCell id: bits 15:8*/
++ u32 pcell_id_2; /* PrimeCell id: bits 23:16*/
++ u32 pcell_id_3; /* PrimeCell id: bits 31:24*/
+};
+
-+ struct msp_mode_status
-+{
-+ int work_mode;
-+ int phase_mode;
-+ int stereo_mode;
-+ volatile u16 *it_mono_data_flow;
-+ volatile u32 *it_stereo_data_flow;
-+ volatile u32 it_halfwords_count;
-+ volatile u32 flow_error_count;
-+} msp_mode_status;
++extern struct irq_desc irq_desc[]; /* interrupt description table */
++static volatile struct vic_register *p_vic_register =
++ (struct vic_register *)IO_ADDRESS(NOMADIK_IC_BASE);
+
++static int nomadik_vic_set_type(unsigned int irq, unsigned int type);
++static DEFINE_SPINLOCK(vic_lock);
+
-+/* Single or dual phase mode */
-+enum
++static void nomadik_vic_priority_mask(unsigned int irq)
+{
-+ MSP_SINGLE_PHASE,
-+ MSP_DUAL_PHASE
-+};
-+
++ u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
++ u32 mask = 1UL<<irq%32;
++ /*
++ * Reading the VIC_VAR register updates the interrupt controllers
++ * hardware priority register to mask lower priority interrupts.
++ * reading is done in entry-macro.S
++ */
++ p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
++ p_vic_register->bank[irq/32].ienc |= mask;
++}
+
-+/* Transmit/Receive shifter status
-+-----------------------------------*/
-+enum
++static void nomadik_vic_priority_unmask(unsigned int irq)
+{
-+ MSP_SxHIFTER_IDLE = 0,
-+ MSP_SHIFTER_WORKING = 1
-+};
++ u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
++ u32 mask = 1UL<<irq%32;
+
++ p_vic_register->vcr[priority_level] |= VIC_VECTORED_IRQ_EN;
++ p_vic_register->bank[irq/32].iens |= mask;
++ /*
++ * Write to the VIC_VAR register.
++ * This clears the respective interrupt in the internal interrupt
++ * priority hardware.
++ */
++ p_vic_register->isr_var = (u32)NULL;
++}
+
-+/* Transmit/Receive FIFO status
-+---------------------------------*/
-+enum
-+{
-+ MSP_FIFO_FULL,
-+ MSP_FIFO_PART_FILLED,
-+ MSP_FIFO_EMPTY
++static struct irq_chip nomadik_vic_priority_chip = {
++ .ack = nomadik_vic_priority_mask,
++ .mask = nomadik_vic_priority_mask,
++ .unmask = nomadik_vic_priority_unmask,
++ .set_type = nomadik_vic_set_type
+};
+
++static void nomadik_vic_mask(unsigned int irq)
++{
++ u32 mask = 1UL<<irq%32;
++ p_vic_register->bank[irq/32].ienc |= mask;
++}
+
-+/* Frame length
-+------------------*/
-+enum
++static void nomadik_vic_unmask(unsigned int irq)
+{
-+ MSP_FRAME_LENGTH_1 = 0,
-+ MSP_FRAME_LENGTH_2 = 1,
-+ MSP_FRAME_LENGTH_4 = 3,
-+ MSP_FRAME_LENGTH_8 = 7,
-+ MSP_FRAME_LENGTH_12 = 11,
-+ MSP_FRAME_LENGTH_16 = 15,
-+ MSP_FRAME_LENGTH_20 = 19,
-+ MSP_FRAME_LENGTH_32 = 31,
-+ MSP_FRAME_LENGTH_48 = 47,
-+ MSP_FRAME_LENGTH_64 = 63
++ u32 mask = 1UL<<irq%32;
++ p_vic_register->bank[irq/32].iens |= mask;
++}
++
++static struct irq_chip nomadik_vic_chip = {
++ .ack = nomadik_vic_mask,
++ .mask = nomadik_vic_mask,
++ .unmask = nomadik_vic_unmask,
++ .set_type = nomadik_vic_set_type
+};
+
-+/* Element length */
-+enum
++/**
++ * nomadik_vic_set_type - To enable/disable/change priority logic
++ *
++ * callback function for set_irq_type sys call
++ * This function will be called in the context of request_irq.
++ * This function is used to configure the interrupt priotity requested
++ * through request_irq sytem call
++ *
++ * This function can be invoked by set_irq_type sys call ,using which
++ * you can enable/disable/change preprogrammed priority
++ *
++ * Note: this function will NOT be invoked if interrupt is requested as
++ * shared irq (i.e. SA_SHIRQ is specifed during requerst_irq),
++ */
++static int nomadik_vic_set_type(unsigned int irq, unsigned int type)
+{
-+ MSP_ELEM_LENGTH_8 = 0,
-+ MSP_ELEM_LENGTH_10 = 1,
-+ MSP_ELEM_LENGTH_12 = 2,
-+ MSP_ELEM_LENGTH_14 = 3,
-+ MSP_ELEM_LENGTH_16 = 4,
-+ MSP_ELEM_LENGTH_20 = 5,
-+ MSP_ELEM_LENGTH_24 = 6,
-+ MSP_ELEM_LENGTH_32 = 7
-+};
++ struct irq_desc *desc;
++ struct irq_chip *vic_chip;
++ unsigned long flags;
+
++ u8 priority_level;
+
-+/* Data delay (in bit clock cycles)
-+---------------------------------------*/
-+enum
-+{
-+ MSP_DELAY_0 = 0,
-+ MSP_DELAY_1 = 1,
-+ MSP_DELAY_2 = 2,
-+ MSP_DELAY_3 = 3
-+};
++ nmdk_dbg_ftrace();
++ if (!irq_desc[irq].action) return(-1); /*if irq not configured*/
++ /*
++ * Priority logic does not work for interrupt configured with
++ * SA_TIMER flag, hence exit if SA_TIMER flag is set for irq
++ */
++ if (irq_desc[irq].action->flags & IRQF_TIMER) return(-1);
++ if ((type & SA_NMDK_PRIORITYIRQ) != SA_NMDK_PRIORITYIRQ) return(-1);
++ /*
++ * if this function is invoked by set_irq_type call
++ * then store input type as flags
++ */
++ if (type > SA_TRIGGER_MASK) irq_desc[irq].action->flags = type;
++ /*process irq priority configuration*/
++ priority_level = (u8)(((irq_desc[irq].action->flags)>>24) & 0x0f);
++ if (p_vic_register->vcr[priority_level] & VIC_VECTORED_IRQ_EN) {
++ nmdk_info("priority change for active irq%d", irq);
++ }
++ /*configure vic for vectored priority interrupt request*/
++ p_vic_register->var[priority_level] = irq;
++ p_vic_register->vcr[priority_level] = irq;
++ /* configure appropriate chip pointer*/
++ desc = irq_desc + irq;
++ if (!priority_level) {
++ p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
++ vic_chip = &nomadik_vic_chip;
++ } else
++ vic_chip = &nomadik_vic_priority_chip;
++ spin_lock_irqsave(&vic_lock, flags);
++ desc->chip = vic_chip;
++ spin_unlock_irqrestore(&vic_lock, flags);
+
++ nmdk_info("Configured PL%2d for irq%d", priority_level, irq);
++ return (0);
++}
+
-+/* Configurations of clocks (transmit, receive or sample rate generator)
-+-------------------------------------------------------------------------*/
-+enum
++static void nomadik_vic_configure(unsigned int irq)
+{
-+ MSP_RISING_EDGE = 0,
-+ MSP_FALLING_EDGE = 1
-+};
++ u32 mask = 1UL<<irq%32;
+
-+/* Protocol dependant parameters list */
-+struct msp_protocol_desc
++ nmdk_dbg("%s for irq %d", __FUNCTION__, irq);
++ /* Select interrupt line as Irq (no FIQ used currently)*/
++ p_vic_register->bank[irq/32].isel &= ~mask;
++}
++
++void __init nomadik_vic_init(void)
+{
-+ u32 phase_mode;
-+ u32 frame_len_1;
-+ u32 frame_len_2;
-+ u32 element_len_1;
-+ u32 element_len_2;
-+ u32 data_delay;
-+ u32 tx_clock_edge;
-+ u32 rx_clock_edge;
-+};
-+
-+#define RX_ENABLE_MASK 0x00000001
-+#define RX_FIFO_ENABLE_MASK 0x00000002
-+#define RX_FRAME_SYNC_MASK 0x00000004
-+#define DIRECT_COMPANDING_MASK 0x00000008
-+#define RX_SYNC_SEL_MASK 0x00000010
-+#define RX_CLK_POL_MASK 0x00000020
-+#define RX_CLK_SEL_MASK 0x00000040
-+#define LOOPBACK_MASK 0x00000080
-+#define TX_ENABLE_MASK 0x00000100
-+#define TX_FIFO_ENABLE_MASK 0x00000200
-+#define TX_FRAME_SYNC_MASK 0x00000400
-+#define TX_SYNC_SEL_MASK 0x00001800
-+#define TX_CLK_POL_MASK 0x00002000
-+#define TX_CLK_SEL_MASK 0x00004000
-+#define TX_EXTRA_DELAY_MASK 0x00008000
-+#define SRG_ENABLE_MASK 0x00010000
-+#define SRG_CLK_POL_MASK 0x00020000
-+#define SRG_CLK_SEL_MASK 0x000C0000
-+#define FRAME_GEN_EN_MASK 0x00100000
-+#define SPI_CLK_MODE_MASK 0x00600000
-+#define SPI_BURST_MODE_MASK 0x00800000
-+
-+#define RXEN_BIT 0
-+#define RFFEN_BIT 1
-+#define RFSPOL_BIT 2
-+#define DCM_BIT 3
-+#define RFSSEL_BIT 4
-+#define RCKPOL_BIT 5
-+#define RCKSEL_BIT 6
-+#define LBM_BIT 7
-+#define TXEN_BIT 8
-+#define TFFEN_BIT 9
-+#define TFSPOL_BIT 10
-+#define TFSSEL_BIT 11
-+#define TCKPOL_BIT 13
-+#define TCKSEL_BIT 14
-+#define TXDDL_BIT 15
-+#define SGEN_BIT 16
-+#define SCKPOL_BIT 17
-+#define SCKSEL_BIT 18
-+#define FGEN_BIT 20
-+#define SPICKM_BIT 21
-+
-+#define msp_rx_clkpol_bit(n) ((n & 1) << RCKPOL_BIT)
-+#define msp_tx_clkpol_bit(n) ((n & 1) << TCKPOL_BIT)
-+#define msp_spi_clk_mode_bits(n) ((n & 3) << SPICKM_BIT)
-+
-+
-+/* Use this to clear the clock mode bits to non-spi */
-+#define MSP_NON_SPI_CLK_MASK 0x00600000
-+
-+#define P1ELEN_BIT 0
-+#define P1FLEN_BIT 3
-+#define DTYP_BIT 10
-+#define ENDN_BIT 12
-+#define DDLY_BIT 13
-+#define FSIG_BIT 15
-+#define P2ELEN_BIT 16
-+#define P2FLEN_BIT 19
-+#define P2SM_BIT 26
-+#define P2EN_BIT 27
-+
-+#define msp_p1_elem_len_bits(n) (n & 0x00000007)
-+#define msp_p2_elem_len_bits(n) (((n) << P2ELEN_BIT) & 0x00070000)
-+#define msp_p1_frame_len_bits(n) (((n) << P1FLEN_BIT) & 0x00000378)
-+#define msp_p2_frame_len_bits(n) (((n) << P2FLEN_BIT) & 0x03780000)
-+#define msp_data_delay_bits(n) (((n) << DDLY_BIT) & 0x00003000)
-+#define msp_data_type_bits(n) (((n) << DTYP_BIT) & 0x00000600)
-+#define msp_p2_start_mode_bit(n) (n << P2SM_BIT)
-+#define msp_p2_enable_bit(n) (n << P2EN_BIT)
-+
-+/* Flag register
-+--------------------*/
-+#define RX_BUSY 0x00000001
-+#define RX_FIFO_EMPTY 0x00000002
-+#define RX_FIFO_FULL 0x00000004
-+#define TX_BUSY 0x00000008
-+#define TX_FIFO_EMPTY 0x00000010
-+#define TX_FIFO_FULL 0x00000020
-+
-+#define RBUSY_BIT 0
-+#define RFE_BIT 1
-+#define RFU_BIT 2
-+#define TBUSY_BIT 3
-+#define TFE_BIT 4
-+#define TFU_BIT 5
-+
-+/* Multichannel control register
-+---------------------------------*/
-+#define RMCEN_BIT 0
-+#define RMCSF_BIT 1
-+#define RCMPM_BIT 3
-+#define TMCEN_BIT 5
-+#define TNCSF_BIT 6
-+
-+/* Sample rate generator register
-+------------------------------------*/
-+#define SCKDIV_BIT 0
-+#define FRWID_BIT 10
-+#define FRPER_BIT 16
-+
-+#define SCK_DIV_MASK 0x0000003FF
-+#define frame_width_bits(n) (((n) << FRWID_BIT) &0x0000FC00)
-+#define frame_period_bits(n) (((n) << FRPER_BIT) &0x1FFF0000)
-+
-+
-+/* DMA controller register
-+---------------------------*/
-+#define RX_DMA_ENABLE 0x00000001
-+#define TX_DMA_ENABLE 0x00000002
-+
-+#define RDMAE_BIT 0
-+#define TDMAE_BIT 1
-+
-+/*Interrupt Register
-+-----------------------------------------*/
-+#define RECEIVE_SERVICE_INT 0x00000001
-+#define RECEIVE_OVERRUN_ERROR_INT 0x00000002
-+#define RECEIVE_FRAME_SYNC_ERR_INT 0x00000004
-+#define RECEIVE_FRAME_SYNC_INT 0x00000008
-+#define TRANSMIT_SERVICE_INT 0x00000010
-+#define TRANSMIT_UNDERRUN_ERR_INT 0x00000020
-+#define TRANSMIT_FRAME_SYNC_ERR_INT 0x00000040
-+#define TRANSMIT_FRAME_SYNC_INT 0x00000080
-+#define ALL_INT 0x000000ff
-+
-+/* Protocol configuration values
-+* I2S: Single phase, 16 bits, 2 words per frame
-+-----------------------------------------------*/
-+#define I2S_PROTOCOL_DESC \
-+{ \
-+ MSP_SINGLE_PHASE, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_ELEM_LENGTH_32, \
-+ MSP_ELEM_LENGTH_32, \
-+ MSP_DELAY_1, \
-+ MSP_FALLING_EDGE, \
-+ MSP_FALLING_EDGE \
-+}
-+
-+/* Companded PCM: Single phase, 8 bits, 1 word per frame
-+--------------------------------------------------------*/
-+#define PCM_COMPAND_PROTOCOL_DESC \
-+{ \
-+ MSP_SINGLE_PHASE, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_ELEM_LENGTH_8, \
-+ MSP_ELEM_LENGTH_8, \
-+ MSP_DELAY_0, \
-+ MSP_RISING_EDGE, \
-+ MSP_FALLING_EDGE \
-+}
-+
-+/* AC97: Double phase, 1 element of 16 bits during first phase,
-+* 12 elements of 20 bits in second phase.
-+--------------------------------------------------------------*/
-+#define AC97_PROTOCOL_DESC \
-+{ \
-+ MSP_DUAL_PHASE, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_FRAME_LENGTH_12, \
-+ MSP_ELEM_LENGTH_16, \
-+ MSP_ELEM_LENGTH_20, \
-+ MSP_DELAY_1, \
-+ MSP_RISING_EDGE, \
-+ MSP_FALLING_EDGE \
-+}
++ unsigned int i;
+
-+#define SPI_MASTER_PROTOCOL_DESC \
-+{ \
-+ MSP_SINGLE_PHASE, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_ELEM_LENGTH_8, \
-+ MSP_ELEM_LENGTH_8, \
-+ MSP_DELAY_1, \
-+ MSP_FALLING_EDGE, \
-+ MSP_RISING_EDGE \
-+}
-+#define SPI_SLAVE_PROTOCOL_DESC \
-+{ \
-+ MSP_SINGLE_PHASE, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_FRAME_LENGTH_1, \
-+ MSP_ELEM_LENGTH_8, \
-+ MSP_ELEM_LENGTH_8, \
-+ MSP_DELAY_1, \
-+ MSP_FALLING_EDGE, \
-+ MSP_RISING_EDGE \
++ nmdk_dbg_ftrace();
++ /*force default isr value to zero*/
++ p_vic_register->isr_dvar = (u32)NULL;
++ for (i = 0; i < MAX_CHIP_IRQ; i++) {
++ if (1ULL<<i & IRQ_CONF) {
++ nomadik_vic_configure(i);
++ set_irq_chip(i, &nomadik_vic_chip);
++ set_irq_handler(i, handle_level_irq);
++ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++ }
++ if (i < VIC_VECTORED_IRQ_NUM) {
++ /*Disable all vectored interrupts */
++ p_vic_register->vcr[i] = (u32)NULL;
++ p_vic_register->var[i] = (u32)NULL;
++ }
++ }
++ nmdk_info("Module initialized Ver("VIC_VER")");
+}
-+#define FUNC_MSP0 GPIO_ALT_MSP_0
-+#define FUNC_MSP1 GPIO_ALT_MSP_1
-+#define FUNC_MSP2 GPIO_ALT_MSP_2
-+
-+#define MSP_FRAME_PERIOD_IN_MONO_MODE 256
-+#define MSP_FRAME_PERIOD_IN_STEREO_MODE 32
-+#define MSP_FRAME_WIDTH_IN_STEREO_MODE 16
-+
-+#define MSP_COUNT 3
-+
-+#endif
-+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/mtu.c ../new/linux-2.6.20/arch/arm/mach-nomadik/mtu.c
---- linux-2.6.20/arch/arm/mach-nomadik/mtu.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/mtu.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,589 @@
-+/*
-+ * Multiple Timer Unit (MTU) driver.
-+ * Written by Vinayak Pane <vinayak.pane@st.com>
-+ *
-+ * Nomadik MTU driver.
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/l2cc.c
+@@ -0,0 +1,152 @@
++/*
++ * linux/arch/arm/mach-nomadik/stn8815_devices.c
+ *
-+ * This driver provides an interface for device drivers to utilize both MTUs.
-+ * which includes total 8 timers, Those can be registered against various purposes
-+ * within kernel.
-+ * It keeps track of used & unused timer units. It handles MTU interrupts
-+ * & their respective multiplexing.
++ * Copyright (C) STMicroelectronics
+ *
-+ * NOTE:
-+ * This device is NOT registered with amba bus device -:
-+ * Even though this driver should be registered with AMBA bus devices,
-+ * we cant do this becasue of Amba driver initialised/probed sequence issue.
-+ * MTU is used as underlying part of system timer. The system timer
-+ * is initialised and used very early before the actual Amba devices
-+ * are initialised/probed. Therefore this probe function is not invoked
-+ * before the system timer is initialised!!
-+ * However we can catergories this driver in platform/system drivers.
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
++ *
++ * SOC specifc drivers whcih are used as amba devices
+ */
-+
++#include <linux/types.h>
++#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
++#include <linux/dma-mapping.h>
+#include <linux/device.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/amba/bus.h>
++#include <linux/amba/kmi.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/spi/spi.h>
++#include <linux/delay.h>
++#include <linux/amba/clcd.h>
+
-+#include <asm/system.h>
-+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
-+
++#include <asm/irq.h>
++#include <asm/dma.h>
++#include <asm/setup.h>
++#include <asm/param.h>
++#include <asm/system.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
+#include <asm/arch/timex.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/arch/mtu.h>
++#include <asm/arch/debug.h>
+
-+#ifdef DEBUG_MTU
-+#define dbg_mtu(format, arg...) printk(KERN_WARNING "" format "\n", ##arg)
-+#else
-+#define dbg_mtu(format, arg...) do { } while (0)
-+#endif
+
-+static irqreturn_t(*mtu_irqs[MTU_MAX_TIMERS + 1]) (mtu_timer_t timer_id) = {
-+NULL};
-+unsigned char mtu_inuse = 0;
-+static spinlock_t mtu_inuse_lock;
++#define L210_CACHE_SYNC 0x730
++#define L210_INV_LINE_PA 0x770
++#define L210_INV_WAY 0x77C
++#define L210_CLEAN_LINE_PA 0x7B0
++#define L210_CLEAN_LINE_IDX 0x7B8
++#define L210_CLEAN_WAY 0x7BC
++#define L210_CLEAN_INV_LINE_PA 0x7F0
++#define L210_CLEAN_INV_LINE_IDX 0x7F8
++#define L210_CLEAN_INV_WAY 0x7FC
+
-+static spinlock_t mtu0_spinlock, mtu1_spinlock;
++static void __iomem *l210_base = (void __iomem *)IO_ADDRESS(NOMADIK_L2CC_BASE);
++static unsigned long way_size = 0x4000;
+
-+ /* functions to read/write control registers */
-+static inline unsigned long mtu_readl(unsigned int timer,
-+ unsigned long ctrl_register)
++static inline void sync_writel(unsigned long val, unsigned long reg,
++ unsigned long complete_mask)
+{
-+ unsigned long value, r_address = MTU_CTRL_REG(timer, ctrl_register);
-+ value = readl(r_address);
-+ return value;
++ writel(val, l210_base + reg);
++ /* wait for the operation to complete not required for l210 controller */
++ //while (readl(l210_base + reg) & complete_mask);
+}
+
-+static inline void mtu_writel(unsigned int timer, long value,
-+ unsigned long ctrl_register)
++static inline void cache_sync(void)
+{
-+ unsigned long w_address = MTU_CTRL_REG(timer, ctrl_register);
-+ writel(value, w_address);
++ sync_writel(0, L210_CACHE_SYNC, 1);
+}
+
-+ /* functions to read/write interrupt registers */
-+inline unsigned long mtu_intr_reg_readl(unsigned int timer,
-+ unsigned long ctrl_register)
++static inline void cacheline_index_op(unsigned long addr, unsigned long reg)
+{
-+ unsigned long value, r_address = MTU_INTR_REG(timer, ctrl_register);
-+ value = readl(r_address);
-+ return value;
-+}
++ unsigned long way, index;
+
-+static inline void mtu_intr_reg_writel(unsigned int timer, long value,
-+ unsigned long ctrl_register)
-+{
-+ unsigned long w_address = MTU_INTR_REG(timer, ctrl_register);
-+ writel(value, w_address);
++ for (way = 0; way < 8; way++)
++ for (index = 0; index < way_size; index += PAGE_SIZE) {
++ unsigned long val = (way << 29) | index | (addr & (PAGE_SIZE - 1));
++ sync_writel(val, reg, 1);
++ }
+}
+
-+static
-+void mtu_set_timer_mode(mtu_timer_t timer, mtu_timer_mode_t mode)
++inline void l210_inv_all(void)
+{
-+ unsigned long timer_cr = 0;
-+
-+ timer_cr = mtu_readl(timer, TyCR); /* read original control register */
-+ switch (mode) {
-+ case MTU_PERIODIC:
-+ timer_cr &= ~MTU_ONE_SHOT; /* clear the one-shot mode */
-+ timer_cr = timer_cr | MTU_PERIODIC;
-+ break;
-+
-+ case MTU_FREE_RUN:
-+ timer_cr = timer_cr & MTU_FREE_RUN;
-+ break;
-+ case MTU_ONE_SHOT:
-+ timer_cr = timer_cr | MTU_ONE_SHOT;
-+ break;
-+ }
-+ mtu_writel(timer, timer_cr, TyCR); /* write back CR */
-+ dbg_mtu("MTU: timer_mode : after CR = %ld\n", timer_cr);
++ /* invalidate all ways */
++ sync_writel(0xff, L210_INV_WAY, 0xff);
++ cache_sync();
+}
++EXPORT_SYMBOL(l210_inv_all);
+
-+#define TyEN 0x0080
-+static int mtu_enable_timer(mtu_timer_t timer)
++inline void l210_clean_all(void)
+{
-+ unsigned long timer_cr = 0;
-+ if (timer > MTU_MAX_TIMERS)
-+ return -1;
-+ timer_cr = mtu_readl(timer, TyCR);
-+ timer_cr |= TyEN;
-+ mtu_writel(timer, timer_cr, TyCR);
-+ dbg_mtu("MTU: After enable timer CR = %ld\n", timer_cr);
-+ return 0;
++ /* clean all ways */
++ sync_writel(0xff, L210_CLEAN_WAY, 0xff);
++ cache_sync();
+}
++EXPORT_SYMBOL(l210_clean_all);
+
-+static void mtu_disable_timer(mtu_timer_t timer)
++inline void l210_flush_all(void)
+{
-+ unsigned long timer_cr;
-+ timer_cr = mtu_readl(timer, TyCR);
-+ timer_cr &= ~(unsigned long)TyEN;
-+ mtu_writel(timer, timer_cr, TyCR);
++ /* clean and invalidate all ways */
++ sync_writel(0xff, L210_CLEAN_INV_WAY, 0xff);
++ cache_sync();
+}
++EXPORT_SYMBOL(l210_flush_all);
+
-+#define TySZ 0x0002
-+static int mtu_change_counter_size(mtu_timer_t timer)
++void l210_inv_range(unsigned long start, unsigned long end)
+{
-+ /* by default the timer counter is 16-bit only,
-+ we can change its size to 32-bit here. */
-+
-+ unsigned long timer_cr = 0;
-+ timer_cr = mtu_readl(timer, TyCR);
-+ timer_cr |= TySZ;
-+ mtu_writel(timer, timer_cr, TyCR);
-+ dbg_mtu("MTU: after change_counter_size CR = %ld\n", timer_cr);
-+ return 0;
++ l210_inv_all();
+}
++EXPORT_SYMBOL(l210_inv_range);
+
-+#define DIVIDE_BY_ONE 0xfffffff3
-+#define DIVIDE_BY_SIXTEEN 0x00000004
-+#define DIVIDE_BY_256 0x00000008
-+
-+static int mtu_change_timer_prescaler(unsigned int timer,
-+ mtu_prescale_t prescaler_factor)
++void l210_clean_range(unsigned long start, unsigned long end)
+{
-+ unsigned long timer_prescaler = 0;
-+ timer_prescaler = mtu_readl(timer, TyCR);
++ unsigned long size = end - start;
++ unsigned long addr;
+
-+ switch (prescaler_factor) {
-+ case MTU_PRESCALE_BY_ONE:
-+ timer_prescaler &= DIVIDE_BY_ONE;
-+ break;
-+ case MTU_PRESCALE_BY_SIXTEEN:
-+ timer_prescaler &= DIVIDE_BY_ONE; /* reset first */
-+ timer_prescaler |= DIVIDE_BY_SIXTEEN; /* set it to 01b now */
-+ break;
-+ case MTU_PRESCALE_BY_256:
-+ timer_prescaler &= DIVIDE_BY_ONE;
-+ timer_prescaler |= DIVIDE_BY_256;
-+ break;
++ if (size >= PAGE_SIZE) {
++ l210_clean_all();
++ return;
+ }
-+ mtu_writel(timer, timer_prescaler, TyCR);
-+ return 0;
-+}
-+unsigned long mtu_get_decrementing_counter_value(mtu_timer_t timer)
-+{
-+ unsigned long decrementing_counter = 0;
-+ decrementing_counter = mtu_readl(timer, TyVAL);
-+ return decrementing_counter;
++
++ /* no physical address information, flush by index/way */
++ for (addr = start & ~(32 - 1); addr < end; addr += 32)
++ cacheline_index_op(addr, L210_CLEAN_LINE_IDX);
++ cache_sync();
+}
++EXPORT_SYMBOL(l210_clean_range);
+
-+EXPORT_SYMBOL(mtu_get_decrementing_counter_value);
+
-+static inline void mtu_load_counter(mtu_timer_t timer,
-+ unsigned long timer_load_register)
++void l210_flush_range(unsigned long start, unsigned long end)
+{
-+ mtu_writel(timer, timer_load_register, TyLR);
-+}
++ unsigned long addr,way,val;
+
-+inline void mtu_bg_load_counter(mtu_timer_t timer,
-+ unsigned long timer_load_register)
-+{
-+ mtu_writel(timer, timer_load_register, TyBGLR);
++ //printk("\nl2 flushing hit\n");
++ /* no physical address information, flush by index/way */
++ for (addr = start & ~(32 - 1); addr < end; addr += 32)
++ cacheline_index_op(addr, L210_CLEAN_INV_LINE_IDX);
++
++ /*for (addr = start; addr < end; addr += 32) {
++ for (way = 0; way < 8; way++) {
++ //val = (way << 29) | ((addr & 0x1ff) << 5);
++ val = (way << 29) | (addr << 5);
++ sync_writel(val, L220_CLEAN_INV_LINE_IDX, 1);
++ }
++ }*/
++ cache_sync();
+}
++EXPORT_SYMBOL(l210_flush_range);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/msp.c
+@@ -0,0 +1,2062 @@
++/*
++ * Driver for Nomadik STN8810/STN8815 MSP device.
++ *
++ * Copyright 2006 STMicroelectronics Pvt. Ltd.
++ *
++ * This program is free sofstware; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ */
+
-+EXPORT_SYMBOL(mtu_bg_load_counter);
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++#include <linux/interrupt.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/amba/bus.h>
++#include <linux/delay.h>
+
-+/***************************************************************
-+ * functiion : mtu0_timer_interrupt_handler
-+ * Description:
-+ * Interrupt of MTU Unit 0 is handled.
-+ * With the priority as MTU0_T0, MTU0_T1,
-+ * MTU0_T2, MTU0_T3. And then the corrosponding
-+ * timer unit's interrupt handler will be called.
-+ * Returns:
-+ * IRQ_HANDLED - ret val from the sub-irq
-+ * IRQ_HANDLED - if the corrosponding irq is not present.
-+ ****************************************************************/
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <asm/irq.h>
+
-+static irqreturn_t mtu0_timer_interrupt_handler(int irq, void *dev_id)
-+{
-+ unsigned long status;
-+ unsigned long icr_flag = 0;
-+ mtu_timer_t timer = 0;
++#include <asm/arch/hardware.h>
++#include <asm/arch/defs.h>
++#include <asm/arch/debug.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/gpio.h>
+
-+ spin_lock(&mtu0_spinlock);
-+ status = mtu_intr_reg_readl(MTU0_T0, TxRIS);
-+ timer = ffs(status);
-+ if ( timer != 1)
-+ {
-+ icr_flag |= 1UL << (timer - 1);
-+ mtu_intr_reg_writel(timer, icr_flag, TxICR); /* clear ICR bit */
-+ }
-+ spin_unlock(&mtu0_spinlock);
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++#include <asm/arch/spi.h>
++#include <asm/arch/msp-spi.h>
++#endif
+
-+ if (likely(mtu_irqs[timer]))
-+ return mtu_irqs[timer] (timer);
-+ else {
-+ dbg_mtu("MTU0:Interrupt on this timer[%d] is not handled.\n",
-+ timer);
-+ return IRQ_HANDLED;
-+ }
++#include <asm/arch/msp.h>
+
-+ return IRQ_HANDLED;
-+}
++#include "msp.h"
+
-+static irqreturn_t mtu1_timer_interrupt_handler(int irq, void *dev_id)
-+{
-+ unsigned long status;
-+ unsigned long icr_flag = 0;
-+ mtu_timer_t timer = 0;
++#ifndef MSP_DEBUG
++#define MSP_DEBUG 0
++#endif
+
-+ spin_lock(&mtu1_spinlock);
-+ status = mtu_intr_reg_readl(MTU1_T0, TxRIS);
-+ /* which timer the interrupt is for */
-+ timer = ffs(status);
-+ icr_flag |= 1UL << (timer - 1);
-+ timer = timer + 4;
-+ mtu_intr_reg_writel(timer, icr_flag, TxICR); /* clear ICR bit */
++#define NMDK_MSP_NAME "NOMADIK_MSP"
+
-+ spin_unlock(&mtu1_spinlock);
-+ /* call corrsponding Irq handler */
-+ if (likely(mtu_irqs[timer]))
-+ return mtu_irqs[timer] (timer);
-+ else {
-+ dbg_mtu("MTU1:Interrupt on this timer[%d] is not handled.\n",
-+ timer);
-+ return IRQ_HANDLED;
-+ }
++#define NMDK_DEBUG MSP_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX NMDK_MSP_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
+
-+ return IRQ_HANDLED;
-+}
++char MSP_NAME[] = "msp";
+
-+struct irqaction mtu0_timer_irq = {
-+ .name = "MTU0 Timer Tick",
-+ .flags = SA_INTERRUPT | IRQF_TIMER,
-+ .handler = mtu0_timer_interrupt_handler,
-+ .dev_id = NULL,
++static volatile struct msp_register *registers[MSP_COUNT] = {
++ (struct msp_register *)IO_ADDRESS(NOMADIK_MSP0_BASE),
++#if MSP_COUNT > 1
++ (struct msp_register *)IO_ADDRESS(NOMADIK_MSP1_BASE),
++#endif
++#if MSP_COUNT > 2
++ (struct msp_register *)IO_ADDRESS(NOMADIK_MSP2_BASE),
++#endif
+};
+
-+struct irqaction mtu1_timer_irq = {
-+ .name = "MTU1 Timer Tick",
-+ .flags = SA_INTERRUPT | IRQF_TIMER,
-+ .handler = mtu1_timer_interrupt_handler,
-+ .dev_id = NULL,
++static int altfunc[MSP_COUNT] = {
++ GPIO_ALT_MSP_0,
++#if MSP_COUNT > 1
++ GPIO_ALT_MSP_1,
++#endif
++#if MSP_COUNT > 2
++ GPIO_ALT_MSP_2,
++#endif
+};
++static int msp_irq = IRQ_MSP0;
+
-+static int mtu_irq_initialize(mtu_timer_t timer,
-+ irqreturn_t(*mtu_sub_irq) (mtu_timer_t timer_id))
-+{
-+ unsigned long icr_flag = 0, clean_icrs = 0;
-+ unsigned long imsc = 0;
-+ unsigned long flags;
-+
-+ if (mtu_sub_irq == NULL)
-+ return -1;
-+
-+ spin_lock(&mtu_inuse_lock);
-+ /* make sure that unregistered timer interrupts are cleared
-+ icr_flag = mtu_intr_reg_readl(timer, TxICR);
-+ : returns Zero always. */
-+ if (timer > 4)
-+ clean_icrs = mtu_inuse >> 4;
-+ else
-+ clean_icrs = mtu_inuse;
-+ /* register the irq sub-handler */
-+ mtu_irqs[timer] = mtu_sub_irq;
-+ spin_unlock(&mtu_inuse_lock);
++static wait_queue_head_t wait[MSP_COUNT];
++static volatile int msp_io_error[MSP_COUNT];
+
-+ /* the INTR bits/registers will be affected here */
-+ if (timer > 4)
-+ spin_lock_irqsave(&mtu1_spinlock, flags);
-+ else
-+ spin_lock_irqsave(&mtu0_spinlock, flags);
++static struct msp_context msp_context[MSP_COUNT];
+
-+ icr_flag = ~clean_icrs;
-+ icr_flag |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
-+ mtu_intr_reg_writel(timer, icr_flag, TxICR);
++static struct msp_mode_status tx_status[MSP_COUNT];
++static struct msp_mode_status rx_status[MSP_COUNT];
+
-+ /* enable interrupt */
-+ imsc = mtu_intr_reg_readl(timer, TxIMSC);
-+ imsc |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
-+ mtu_intr_reg_writel(timer, imsc, TxIMSC);
++static u32 input_clock[MSP_COUNT];
++static u32 spi_clock_mode[MSP_COUNT];
++static u32 spi_burst_mode[MSP_COUNT];
+
-+ if (timer > 4)
-+ spin_unlock_irqrestore(&mtu1_spinlock, flags);
-+ else
-+ spin_unlock_irqrestore(&mtu0_spinlock, flags);
-+ return 0;
-+}
++/*Usage Flag for MSPs*/
++msp_flag *flag_msp0, *flag_msp1, *flag_msp2;
+
-+int mtu_register_timer(struct mtu_struct *mtu)
++static const struct msp_protocol_desc protocol_desc_tab[] = /* Protocol desciptors */
+{
-+ u64 mtu_interval_ns;
-+ mtu_prescale_t mtu_prescale;
-+ if (mtu == NULL)
-+ return -EINVAL;
-+ if (mtu->timer > MTU_MAX_TIMERS)
-+ return -EINVAL;
++ I2S_PROTOCOL_DESC,
++ /* PCM_PROTOCOL_DESC */
++ {
++ MSP_SINGLE_PHASE,
++ MSP_FRAME_LENGTH_1,
++ MSP_FRAME_LENGTH_1,
++ MSP_ELEM_LENGTH_16,
++ MSP_ELEM_LENGTH_16,
++ /*below three settings are platform specific */
++ MSP_DATA_DELAY,
++ MSP_TX_CLOCK_EDGE,
++ MSP_RX_CLOCK_EDGE},
++ PCM_COMPAND_PROTOCOL_DESC,
++ AC97_PROTOCOL_DESC,
++ SPI_MASTER_PROTOCOL_DESC,
++ SPI_SLAVE_PROTOCOL_DESC
++};
++/* local functions */
++static irqreturn_t handle_irq(int irq, void *dev_id);
++static int transmit_data(int msp, void *data, size_t bytes);
++static int receive_data(int msp, void *data, size_t bytes);
++static int transmit_receive_data(int msp, int work_mode,
++ void *txdata, size_t txbytes, void *rxdata,
++ size_t rxbytes);
++static int configure_clock(int msp, int protocol, u32 input_clock,
++ u32 frame_freq, int frame_size);
++static int configure_protocol(int msp, int protocol, int direction,
++ enum msp_data_size data_size);
+
-+#ifndef CONFIG_NOMADIK_MTU_SYSTEM_TICK
-+ /* if the MTU0 IRQ is not set here, we cant use the timers:
-+ * MTU0_T0, MTU0_T1, MTU0_T2 & MTU0_T3
-+ */
-+ if (mtu->timer <= 4) {
-+ printk(KERN_WARNING
-+ "MTU: Can not register, since MTU0 support is absent.\n");
-+ return -EINVAL;
-+ }
-+#endif
+
-+ spin_lock(&mtu_inuse_lock);
-+ if (mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) {
-+ printk(KERN_WARNING
-+ "MTU: This timer unit is already in use.\n");
-+ spin_unlock(&mtu_inuse_lock);
-+ return -EBUSY;
-+ } else {
-+ mtu_inuse |= (unsigned char)0x1 << (mtu->timer - 1);
-+ }
-+ spin_unlock(&mtu_inuse_lock);
++/**
++ * nomadik_msp_configure - configures the MSP controller
++ * @msp - specifies the msp controller to configure.
++ * @config - specifies the configuration parameters.
++ */
++int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user)
++{
++ u32 old_reg;
++ u32 new_reg;
++ u32 mask;
++ int status = 0;
+
-+ if (mtu->mtu_irq) {
-+ mtu_irq_initialize(mtu->timer, mtu->mtu_irq);
-+ } else {
-+ printk(KERN_WARNING
-+ "MTU: Must specify the action handler for timer.\n");
++ if (msp < 0 || msp > MSP_COUNT) {
++ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
+ return -EINVAL;
+ }
++ nmdk_dbg("In nomadik_msp_configure, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
++ nmdk_dbg("In nomadik_msp_configure, flag_msp1 is %d\n", flag_msp1->user);
++ nmdk_dbg("In nomadik_msp_configure, flag_msp2 is %d\n", flag_msp2->user);
+
-+ mtu_set_timer_mode(mtu->timer, mtu->mode);
-+ mtu_interval_ns = ktime_to_ns(mtu->interval);
-+
-+ /* calculate the timer load register value from ktime(sec,nsec) format */
-+#if BITS_PER_LONG != 64
-+ /* XXX the arithmatic part shall be replaced by ktime_ns-ops */
-+ dbg_mtu("MTU: nano second interval passed is : %lld \n",
-+ mtu_interval_ns);
-+
-+ if (mtu_interval_ns / USEC_PER_SEC < (0x6FA * MSEC_PER_SEC)) {
-+ mtu_prescale = MTU_PRESCALE_BY_ONE;
-+ mtu_interval_ns = mtu_interval_ns * 24 * MSEC_PER_SEC;
-+ do_div(mtu_interval_ns, 10);
-+ } else {
-+ if (mtu_interval_ns / USEC_PER_SEC < (0xB2F * MSEC_PER_SEC)) {
-+ mtu_prescale = MTU_PRESCALE_BY_SIXTEEN;
-+ mtu_interval_ns = mtu_interval_ns * 15 * MSEC_PER_SEC;
-+ do_div(mtu_interval_ns, 100);
-+ } else {
-+ mtu_prescale = MTU_PRESCALE_BY_256;
-+ mtu_interval_ns = mtu_interval_ns * 93 * MSEC_PER_SEC;
-+ do_div(mtu_interval_ns, 10000);
-+ }
++ switch(msp) {
++ case 0: if((flag_msp0->user != MSP_NO_USER) && (flag_msp0->user != user)){
++ status = -EINVAL;
++ printk(KERN_ERR "MSP0 already in use in %d mode", flag_msp0->user);
++ }
++ else {
++ down(&flag_msp0->lock);
++ flag_msp0->user = user;
++ up(&flag_msp0->lock);
++ }
++ break;
++ case 1: if((flag_msp1->user != MSP_NO_USER) && (flag_msp1->user != user)){
++ status = -EINVAL;
++ printk(KERN_ERR "MSP1 already in use in %d mode", flag_msp1->user);
++ }
++ else {
++ down(&flag_msp1->lock);
++ flag_msp1->user = user;
++ up(&flag_msp1->lock);
++ }
++ break;
++ case 2: if((flag_msp2->user != MSP_NO_USER) && (flag_msp2->user != user)){
++ status = -EINVAL;
++ printk(KERN_ERR "MSP2 already in use in %d mode", flag_msp2->user);
++ }
++ else
++ down(&flag_msp2->lock);
++ flag_msp2->user = user;
++ up(&flag_msp2->lock);
++ break;
+ }
-+
-+ do_div(mtu_interval_ns, USEC_PER_SEC);
-+
-+ if (mtu_interval_ns >> 32) {
-+ printk(KERN_WARNING
-+ "MTU: The interval specified is too big to fit in reload value.\n");
-+ spin_lock(&mtu_inuse_lock);
-+ mtu_irqs[mtu->timer] = NULL;
-+ spin_unlock(&mtu_inuse_lock);
-+ return -EINVAL;
++ if(status) {
++ printk(KERN_ERR "Error in setting flag bit for MSP\n");
++ return status;
+ }
+
-+ dbg_mtu("MTU: setting the prescaler of timer to [%x]\n", mtu_prescale);
-+ mtu_change_timer_prescaler(mtu->timer, mtu_prescale);
++ /* First do the global config register */
++ mask =
++ RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FRAME_SYNC_MASK |
++ TX_FRAME_SYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
++ RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK;
+
-+ if (mtu_interval_ns >> 16) {
-+ dbg_mtu("MTU: changing the counter size to 32 bits\n");
-+ mtu_change_counter_size(mtu->timer);
-+ }
++ new_reg =
++ (config->tx_clock_sel | config->rx_clock_sel | config->
++ rx_frame_sync_pol | config->tx_frame_sync_pol | config->
++ rx_frame_sync_sel | config->tx_frame_sync_sel | config->
++ rx_fifo_config | config->tx_fifo_config | config->srg_clock_sel);
+
-+ dbg_mtu("MTU:Using %lld as calculated interval for timer\n",
-+ mtu_interval_ns);
-+ /* lets ignore the LSB part now, MTU supports 32bit counter regi only */
-+ mtu_load_counter(mtu->timer, mtu_interval_ns);
++ old_reg = (registers[msp]->global_ctrl);
++ old_reg &= ~mask;
++ old_reg |= new_reg;
++ (registers[msp]->global_ctrl) = old_reg;
+
-+ /* XXX: if BG-load-register is passed we have to calculate the
-+ * mtu_bg_interval_ns load value and then load it. */
-+ if (mtu->bg_interval.tv64 == mtu->interval.tv64) /* right now, this much is supported */
-+ mtu_bg_load_counter(mtu->timer, mtu_interval_ns);
++ /* Now do the tx_config and rx_config registers */
++ old_reg = registers[msp]->rx_config;
++ mask = MSP_NON_MODE_BIT_MASK;
++ new_reg = config->rx_endianess | config->rx_unexpect_frame_sync;
++ old_reg &= ~mask;
++ old_reg |= new_reg;
++ (registers[msp]->rx_config) = old_reg;
++ old_reg = registers[msp]->tx_config;
++ new_reg = config->tx_endianess | config->tx_unexpect_frame_sync;
++ old_reg &= ~mask;
++ old_reg |= new_reg;
++ (registers[msp]->tx_config) = old_reg;
+
-+ /* finally enable and start the timer */
-+ mtu_enable_timer(mtu->timer);
-+#else
-+ printk(KERN_WARNING "MTU:Functionality is not implemented!\n");
-+#endif
++ /* Set global input clock and spi clock mode, needed by other config ops */
+
++ input_clock[msp] = config->input_clock_freq;
++ spi_clock_mode[msp] = config->spi_clk_mode;
++ spi_burst_mode[msp] = config->spi_burst_mode;
+ return 0;
+}
+
-+EXPORT_SYMBOL(mtu_register_timer);
-+
-+int mtu_unregister_timer(struct mtu_struct *mtu)
++/**
++ * nomadik_msp_enable - Enable the msp controller with given configuration
++ * @msp - specifies the msp controller
++ * @direction - specifies the transmit/receive direction
++ * @work_mode - specifies DMA/Interrupt/Polling mode
++ * @protocol - Either PCM/I2S
++ * @frame_freq - specifies the frequency.
++ * @frame_size - specifies frame size
++ * @data_size - specifies element size
++ */
++int nomadik_msp_enable(int msp, int direction, int work_mode, int protocol,
++ int frame_freq, int frame_size,
++ enum msp_data_size data_size, t_msp_user user)
+{
-+ unsigned long icr_clear = 0, imsc;
-+ unsigned long flags;
-+ icr_clear |=
-+ 1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1));
-+
-+ spin_lock(&mtu_inuse_lock);
-+
-+ /* check if the caller has right to unregister this timer */
-+ if (mtu->mtu_irq != mtu_irqs[mtu->timer]) {
-+ unregister_failed:
-+ spin_unlock(&mtu_inuse_lock);
++ int status = 0;
++ int skip_irq;
++ if (msp < 0 || msp > MSP_COUNT) {
++ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
+ return -EINVAL;
+ }
+
-+ if ((mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) == 0) {
-+ /* if the timer unit was not registered successfully */
-+ goto unregister_failed;
-+ } else
-+ /* clear the inuse bit */
-+ mtu_inuse &= ~((unsigned char)0x1 << (mtu->timer - 1));
-+ spin_unlock(&mtu_inuse_lock);
++ nmdk_dbg("In nomadik_msp_enable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
++ switch(msp) {
++ case 0: if(flag_msp0->user != user) {
++ status = -EINVAL;
++ printk(KERN_ERR "MSP0 not usable in Non SPI mode\n");
++ }
++ break;
++ case 1: if(flag_msp1->user != user) {
++ status = -EINVAL;
++ printk(KERN_ERR "MSP1 not usable in Non SPI mode\n");
++ }
++ break;
++ case 2: if(flag_msp2->user != user) {
++ status = -EINVAL;
++ printk(KERN_ERR "MSP2 not usable in Non SPI mode\n");
++ }
++ break;
++ }
++ if(status) {
++ printk(KERN_ERR "Error in setting flag bit for MSP, status is %d\n", status);
++ return status;
++ }
+
-+ if (mtu->timer > 4)
-+ spin_lock_irqsave(&mtu1_spinlock, flags);
-+ else
-+ spin_lock_irqsave(&mtu0_spinlock, flags);
++ skip_irq = (registers[msp]->global_ctrl) & (TX_ENABLE | RX_ENABLE);
+
-+ mtu_disable_timer(mtu->timer);
++ if(!skip_irq) {
++ switch (msp) {
++ case 0:
++ status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_0");
++ break;
++ case 1:
++ status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_1");
++ break;
++ case 2:
++ status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_2");
++ break;
++ }
++ if (status) {
++ printk(KERN_ERR "Error in nomadik_gpio_altfuncenable, status is %d\n", status);
++ return status;
++ }
++ }
+
-+ /* disable the interrupt */
-+ imsc = mtu_intr_reg_readl(mtu->timer, TxIMSC);
-+ imsc &=
-+ ~(1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1)));
-+ mtu_intr_reg_writel(mtu->timer, imsc, TxIMSC);
++ /* Store context data for power management */
++ msp_context[msp].direction = direction;
++ msp_context[msp].mode = work_mode;
++ msp_context[msp].protocol = protocol;
++ msp_context[msp].frame_freq = frame_freq;
++ msp_context[msp].frame_size = frame_size;
++ msp_context[msp].requested_data_size = data_size;
+
-+ /* clear the interrupt of this timer */
-+ mtu_intr_reg_writel(mtu->timer, icr_clear, TxICR);
++ /* Configure msp with protocol dependent settings */
++ configure_protocol(msp, protocol, direction, data_size);
+
-+ mtu_load_counter(mtu->timer, 0);
++ configure_clock(msp, protocol, input_clock[msp], frame_freq,
++ frame_size);
+
-+ spin_lock(&mtu_inuse_lock);
-+ mtu_irqs[mtu->timer] = NULL;
-+ spin_unlock(&mtu_inuse_lock);
++ switch (direction) {
++ case MSP_TRANSMIT_MODE:
++ registers[msp]->irq_mask |= TRANSMIT_UNDERRUN_ERR_INT;
++ if (work_mode == MSP_DMA_MODE) {
++ registers[msp]->dma_ctrl |= TX_DMA_ENABLE;
++ }
+
-+ if (mtu->timer > 4)
-+ spin_unlock_irqrestore(&mtu1_spinlock, flags);
-+ else
-+ spin_unlock_irqrestore(&mtu0_spinlock, flags);
++ tx_status[msp].work_mode = work_mode;
++ if (protocol == MSP_I2S_PROTOCOL) {
++ tx_status[msp].stereo_mode = MSP_STEREO;
++ } else {
++ tx_status[msp].stereo_mode = MSP_MONO;
++ }
+
-+ return 0;
-+}
++ (registers[msp]->global_ctrl) &= ~RX_ENABLE;
++ (registers[msp]->global_ctrl) |= TX_ENABLE;
++ break;
++ case MSP_RECEIVE_MODE:
++ registers[msp]->irq_mask |= RECEIVE_OVERRUN_ERROR_INT;
++ if (work_mode == MSP_DMA_MODE) {
++ registers[msp]->dma_ctrl |= RX_DMA_ENABLE;
++ }
+
-+EXPORT_SYMBOL(mtu_unregister_timer);
++ rx_status[msp].work_mode = work_mode;
++ if (protocol == MSP_I2S_PROTOCOL) {
++ rx_status[msp].stereo_mode = MSP_STEREO;
++ } else {
++ rx_status[msp].stereo_mode = MSP_MONO;
++ }
+
-+static struct {
-+ u32 tmr_value;
-+ u32 tmr_control;
-+ u32 tmr_bgload;
-+}mtu_tmr_context[8];
++ (registers[msp]->global_ctrl) |= RX_ENABLE;
++ (registers[msp]->global_ctrl) &= ~TX_ENABLE;
++ break;
++ case MSP_BOTH_T_R_MODE:
++ registers[msp]->irq_mask |=
++ TRANSMIT_UNDERRUN_ERR_INT | RECEIVE_OVERRUN_ERROR_INT;
++ if (work_mode == MSP_DMA_MODE) {
++ registers[msp]->dma_ctrl |=
++ TX_DMA_ENABLE | RX_DMA_ENABLE;
++ }
+
-+static u32 nomadik_mtu0_imsc[2];
++ tx_status[msp].work_mode = work_mode;
++ rx_status[msp].work_mode = work_mode;
++ if (protocol == MSP_I2S_PROTOCOL) {
++ tx_status[msp].stereo_mode = MSP_STEREO;
++ rx_status[msp].stereo_mode = MSP_STEREO;
++ } else {
++ tx_status[msp].stereo_mode = MSP_MONO;
++ rx_status[msp].stereo_mode = MSP_MONO;
++ }
+
-+int nomadik_mtu_suspend(void)
-+{
-+ /* Use spin lock */
-+ int inuse = mtu_inuse & ~1;
-+ int tmr_no;
++ (registers[msp]->global_ctrl) |= RX_ENABLE;
++ (registers[msp]->global_ctrl) |= TX_ENABLE;
++ break;
++ default:
++ printk(KERN_ERR "Invalid direction parameter\n");
++ return -EINVAL;
++ }
+
-+ nomadik_mtu0_imsc[0] = mtu_intr_reg_readl(MTU0_T0, TxIMSC);
-+ nomadik_mtu0_imsc[1] = mtu_intr_reg_readl(MTU1_T0, TxIMSC);
-+ while(inuse)
-+ {
-+ tmr_no = ffs(inuse);
-+ mtu_tmr_context[tmr_no-1].tmr_value = mtu_readl(tmr_no, TyVAL);
-+ mtu_tmr_context[tmr_no-1].tmr_control = mtu_readl(tmr_no, TyCR);
-+ mtu_tmr_context[tmr_no-1].tmr_bgload = mtu_readl(tmr_no, TyBGLR);
-+ inuse = inuse & ~(1 << ( tmr_no - 1 ));
++ /* enable frame generation logic */
++ (registers[msp]->global_ctrl) |= FRAME_GEN_ENABLE;
++ msp_context[msp].msp_disable = 0;
++ if (!skip_irq) {
++ status = request_irq(msp_irq, handle_irq,
++ SA_INTERRUPT | SA_SHIRQ, MSP_NAME,
++ (void *)registers[msp]);
++ if(status)
++ printk(KERN_ERR "Error while request_irq, err is %d\n", status);
+ }
-+ return 0;
++ return status;
+}
+
-+int nomadik_mtu_resume(void)
++void nomadik_msp_flush_input(int msp)
+{
-+ /* Use spin lock */
-+ int inuse = mtu_inuse & ~1;
-+ int tmr_no;
-+
-+ mtu_intr_reg_writel(MTU0_T0, nomadik_mtu0_imsc[0], TxIMSC);
-+ mtu_intr_reg_writel(MTU1_T0, nomadik_mtu0_imsc[1], TxIMSC);
-+ while(inuse)
-+ {
-+ tmr_no = ffs(inuse);
-+ mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_value, TyLR);
-+ mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_control, TyCR);
-+ mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_bgload, TyBGLR);
-+ inuse = inuse & ~(1 << ( tmr_no - 1 ));
++ u32 dummy;
++ while (!(registers[msp]->status & RX_FIFO_EMPTY)) {
++ dummy = registers[msp]->fifo;
+ }
-+ return 0;
+}
+
-+
-+int __init nomadik_mtu_init(void)
++int nomadik_msp_send_data(int msp, void *data, size_t bytes)
+{
-+ unsigned long all_icr_clear = 0xf;
-+ volatile unsigned long *psrc_cr =
-+ (volatile unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE);
-+ unsigned long src_cr;
-+ src_cr = *psrc_cr;
-+ src_cr |= 0x2AAA8000;
-+ *psrc_cr = src_cr;
++ int status;
+
-+ spin_lock_init(&mtu0_spinlock);
-+ spin_lock_init(&mtu1_spinlock);
++ if (msp < 0 || msp > MSP_COUNT) {
++ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++ return -EINVAL;
++ }
+
-+ mtu_irqs[0] = NULL;
-+ /* clear the interrupts */
++ if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
++ printk(KERN_ERR
++ "Trying to transmit with transmit not enabled\n");
++ return -EPERM;
++ }
+
-+ mtu_intr_reg_writel(MTU1_T0, all_icr_clear, TxICR);
++ switch (tx_status[msp].work_mode) {
++ case MSP_DMA_MODE:
++ printk(KERN_WARNING "Function not authorized in DMA mode\n");
++ return -ENOSYS;
++ break;
++ case MSP_POLLING_MODE:
++ case MSP_INTERRUPT_MODE:
++ status = transmit_data(msp, data, bytes);
++ break;
++ default:
++ printk(KERN_ERR "tx work mode invalid: %d\n",
++ tx_status[msp].work_mode);
++ return -EINVAL;
++ break;
++ }
+
-+ /*
-+ * setup an interrupt for the Timer units
-+ */
-+#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
-+ /* Cannt use if module! It might screw the system "timer_tick" */
-+ mtu_intr_reg_writel(MTU0_T0, all_icr_clear, TxICR);
++ return status;
++}
+
-+ setup_irq(IRQ_MTU0, &mtu0_timer_irq);
-+ printk(KERN_INFO "MTU: Registered MTU0 timer unit.\n");
++int nomadik_msp_receive_data(int msp, void *data, size_t bytes)
++{
++ int status;
+
-+ setup_irq(IRQ_MTU1, &mtu1_timer_irq);
-+ printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
-+#else
-+ request_irq(IRQ_MTU1, mtu1_timer_irq.handler, mtu1_timer_irq.flags,
-+ mtu1_timer_irq.name, NULL);
-+ printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
-+#endif
++ if (msp < 0 || msp > MSP_COUNT) {
++ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++ return -EINVAL;
++ }
+
-+ return 0;
++ if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
++ printk(KERN_ERR "Trying to receive with receive not enabled\n");
++ return -EPERM;
++ }
++
++ switch (rx_status[msp].work_mode) {
++ case MSP_DMA_MODE:
++ printk(KERN_WARNING "Function not authorized in DMA mode\n");
++ return -ENOSYS;
++ break;
++ case MSP_POLLING_MODE:
++ case MSP_INTERRUPT_MODE:
++ status = receive_data(msp, data, bytes);
++ break;
++ default:
++ printk(KERN_ERR "rx work mode invalid: %d\n",
++ rx_status[msp].work_mode);
++ return -EINVAL;
++ break;
++ }
++
++ return status;
+}
+
-+void __exit nomadik_mtu_exit(void)
++int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
++ void *rxdata, size_t rxbytes)
+{
-+ mtu_timer_t timer;
-+ /* disabling the registered timers */
-+ while (mtu_inuse) {
-+ timer = ffs(mtu_inuse);
-+ mtu_disable_timer(timer);
-+ mtu_inuse &= ~((unsigned char)0x1 << timer);
++ int status;
++
++ if (msp < 0 || msp > MSP_COUNT) {
++ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++ return -EINVAL;
+ }
+
-+ free_irq(IRQ_MTU1, NULL);
++ if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
++ printk(KERN_ERR "Trying to receive with receive not enabled\n");
++ return -EPERM;
++ }
+
-+#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
-+ free_irq(IRQ_MTU0, NULL);
-+#endif
-+}
++ if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
++ printk(KERN_ERR
++ "Trying to transmit with transmit not enabled\n");
++ return -EPERM;
++ }
+
-+#ifndef CONFIG_MTU0
-+module_init(nomadik_mtu_init);
-+#endif
-+module_exit(nomadik_mtu_exit);
++ if (tx_status[msp].work_mode != rx_status[msp].work_mode) {
++ printk(KERN_ERR "Inconsistent transmit/reveive modes\n");
++ return -EINVAL;
++ }
+
-+MODULE_LICENSE("Proprietary");
-+MODULE_DESCRIPTION("Nomadik MTU Driver");
-+MODULE_AUTHOR("ST Microelectronics");
++ switch (tx_status[msp].work_mode) {
++ case MSP_DMA_MODE:
++ printk(KERN_WARNING "Function not authorized in DMA mode\n");
++ return -ENOSYS;
++ break;
++ case MSP_POLLING_MODE:
++ case MSP_INTERRUPT_MODE:
++ status = transmit_receive_data(msp, tx_status[msp].work_mode,
++ txdata, txbytes,
++ rxdata, rxbytes);
++ break;
++ default:
++ printk(KERN_ERR "work mode invalid: %d\n",
++ tx_status[msp].work_mode);
++ return -EINVAL;
++ break;
++ }
+
-+/* vim: set ts=4 noet sw=4 */
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,28 @@
-+if NOMADIK_NDK10_CUT_A1
++ return status;
++}
+
-+#target name configuration
-+config NOMADIK_TARGET
-+ string
-+ default NDK10_Cut_A1
-+
-+# nomadik soc chip name configuration for this target
-+config NOMADIK_SOC
-+ string
-+ default stn8810
++static int nomadik_msp_wait_for_tx_complete(int msp)
++{
++ while (!(registers[msp]->status & TX_FIFO_EMPTY));
++ return 0;
++}
+
-+# nomadik platform name configuration for this target
-+config NOMADIK_PLATFORM
-+ string
-+ default ndk10
++/**
++ * nomadik_msp_disable - disable the given msp controller
++ * @msp - specifies the msp contoller
++ * @direction - specifies the transmit/receive direction
++ */
++int nomadik_msp_disable(int msp, int direction, t_msp_user user)
++{
++ int status = 0;
++ if (msp < 0 || msp > MSP_COUNT) {
++ printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++ return -EINVAL;
++ }
+
-+# EXTRA_CFLAGS configuration for this target
-+config NOMADIK_TARGET_EXTRA_CFLAGS
-+ string
-+ default "-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++ nmdk_dbg("In nomadik_msp_disable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
++ /*Set global flag to free state*/
++ switch(msp) {
++ case 0: if(flag_msp0->user == user) {
++ down(&flag_msp0->lock);
++ flag_msp0->user = MSP_NO_USER;
++ up(&flag_msp0->lock);
++ nmdk_dbg("Flag cleanup for MSP0\n");
++ }
++ else {
++ nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp0->user);
++ status = -EFAULT;
++ }
++ break;
++ case 1: if(flag_msp1->user == user) {
++ down(&flag_msp1->lock);
++ flag_msp1->user = MSP_NO_USER;
++ up(&flag_msp1->lock);
++ nmdk_dbg("Flag cleanup for MSP1\n");
++ }
++ else {
++ nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp1->user);
++ status = -EFAULT;
++ }
++ break;
++ case 2: if(flag_msp2->user == user) {
++ down(&flag_msp2->lock);
++ flag_msp2->user = MSP_NO_USER;
++ up(&flag_msp2->lock);
++ nmdk_dbg("Flag cleanup for MSP2\n");
++ }
++ else {
++ nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp2->user);
++ status = -EFAULT;
++ }
++ break;
++ }
++ if(status)
++ return status;
+
-+# Basic platform type configuration for this target (optional will be removed latter)
-+config NOMADIK_NDK10
-+ bool
-+ default y
++ if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
++ goto disable_alt;
++ }
+
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,35 @@
-+if NOMADIK_NDK10_CUT_B06
++ if (direction != MSP_RECEIVE_MODE) {
++ int status = nomadik_msp_wait_for_tx_complete(msp);
++ if (status) {
++ goto disable_alt;
++ }
++ }
++ switch (direction) {
++ case MSP_RECEIVE_MODE:
++ registers[msp]->global_ctrl &= ~RX_ENABLE;
++ registers[msp]->dma_ctrl &= ~RX_DMA_ENABLE;
++ registers[msp]->irq_mask &= ~(RECEIVE_SERVICE_INT |
++ RECEIVE_OVERRUN_ERROR_INT);
++ rx_status[msp].flow_error_count = 0;
++ break;
++ case MSP_TRANSMIT_MODE:
++ registers[msp]->global_ctrl &= ~TX_ENABLE;
++ registers[msp]->dma_ctrl &= ~TX_DMA_ENABLE;
++ registers[msp]->irq_mask &= ~(TRANSMIT_SERVICE_INT |
++ TRANSMIT_UNDERRUN_ERR_INT);
++ tx_status[msp].flow_error_count = 0;
++ break;
++ case MSP_BOTH_T_R_MODE:
++ registers[msp]->global_ctrl &= ~(TX_ENABLE | RX_ENABLE);
++ registers[msp]->dma_ctrl &= ~(TX_DMA_ENABLE | RX_DMA_ENABLE);
++ registers[msp]->irq_mask &= ~ALL_INT;
++ tx_status[msp].flow_error_count = 0;
++ rx_status[msp].flow_error_count = 0;
++ break;
++ default:
++ printk(KERN_ERR "Invalid direction param\n");
++ status = -EINVAL;
++ goto disable_alt;
++ }
+
-+comment "Nomadik chip used STRn8810B2S12HPB cut B (chip secure)"
++ msp_context[msp].msp_disable = 1;
+
-+#target name configuration for this target
-+config NOMADIK_TARGET
-+ string
-+ default NDK10_Cut_B06
-+
-+# nomadik soc chip name configuration for this target
-+config NOMADIK_SOC
-+ string
-+ default stn8810
++ if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
++ /* disable sample rate and frame generators */
++ registers[msp]->global_ctrl &= ~(FRAME_GEN_ENABLE | SRG_ENABLE);
+
-+# nomadik soc chip cut name configuration for this targe only
-+config NOMADIK_STRn8810B2S12HPB
-+ bool
-+ default y
++ free_irq(msp_irq, (void *)registers[msp]);
++ }
+
-+# nomadik platform name configuration for this target
-+config NOMADIK_PLATFORM
-+ string
-+ default ndk10
+
-+# EXTRA_CFLAGS configuration for this target
-+config NOMADIK_TARGET_EXTRA_CFLAGS
-+ string
-+ default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++disable_alt:
++ switch (msp) {
++ case 0:
++ nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_0");
++ break;
++ case 1:
++ nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_1");
++ break;
++ case 2:
++ nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_2");
++ break;
++ }
+
-+# Basic platform type configuration for this target
-+config NOMADIK_NDK10
-+ bool
-+ default y
++ return status;
++}
+
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,35 @@
-+if NOMADIK_NDK10_CUT_B0
++static int configure_protocol(int msp, int protocol, int direction,
++ enum msp_data_size data_size)
++{
++ u32 temp_reg;
+
-+comment "Nomadik chip used STRn8810B2S12 cut B"
++ if ((protocol < 0) || (protocol >= MSP_INVALID_PROTOCOL)) {
++ printk(KERN_ERR
++ "invalid protocol requested in configure_protocol()\n");
++ return -EINVAL;
++ }
+
-+#target name configuration for this target
-+config NOMADIK_TARGET
-+ string
-+ default NDK10_Cut_B0
-+
-+# nomadik soc chip name configuration for this target
-+config NOMADIK_SOC
-+ string
-+ default stn8810
++ if (data_size < MSP_DATA_SIZE_DEFAULT
++ || data_size > MSP_DATA_SIZE_32BIT) {
++ printk(KERN_ERR
++ "invalid data size requested in configure_protocol()\n");
++ return -EINVAL;
++ }
+
-+# nomadik soc chip cut name configuration for this targe only
-+config NOMADIK_STRn8810B2S12
-+ bool
-+ default y
++ switch (direction) {
++ case MSP_TRANSMIT_MODE:
++ tx_status[msp].phase_mode =
++ protocol_desc_tab[protocol].phase_mode;
+
-+# nomadik platform name configuration for this target
-+config NOMADIK_PLATFORM
-+ string
-+ default ndk10
++ /* Use a temp for setup. Clear everything except the two non-mode
++ * dependent bits, then add back the bits for the selected protocol
++ */
++ temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
+
-+# EXTRA_CFLAGS configuration for this target
-+config NOMADIK_TARGET_EXTRA_CFLAGS
-+ string
-+ default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++ temp_reg |=
++ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++ temp_reg |=
++ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_1);
++ temp_reg |=
++ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_2);
++ if (data_size == MSP_DATA_SIZE_DEFAULT) {
++ temp_reg |=
++ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_1);
++ temp_reg |=
++ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_2);
++ if (protocol_desc_tab[protocol].element_len_1 ==
++ protocol_desc_tab[protocol].element_len_2) {
++ msp_context[msp].actual_data_size =
++ protocol_desc_tab[protocol].element_len_1;
++ } else {
++ msp_context[msp].actual_data_size = data_size;
++ }
++ } else {
++ temp_reg |= msp_p1_elem_len_bits(data_size);
++ temp_reg |= msp_p2_elem_len_bits(data_size);
++ msp_context[msp].actual_data_size = data_size;
++ }
++ temp_reg |=
++ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
+
-+# Basic platform type configuration for this target
-+config NOMADIK_NDK10
-+ bool
-+ default y
++ (registers[msp]->tx_config) = temp_reg;
+
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1225 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/ndk10_devices.c
-+ *
-+ * Copyright (C) 2000-2003 Deep Blue Solutions Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/amba/bus.h>
-+#include <linux/spi/spi.h>
-+#include <linux/amba/kmi.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/setup.h>
-+#include <asm/param.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/time.h>
-+#include <asm/arch/i2c.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/kpd.h>
-+#include <asm/arch/touchp.h>
-+#include <asm/arch/fsmc.h>
-+#ifdef CONFIG_MTD
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/concat.h>
-+#include <asm/arch/nandflash.h>
-+#include <asm/mach/flash.h>
-+#endif
-+#include <asm/arch/debug.h>
++ /* The tx_config register is done, now set the clock mode (rising
++ * or falling edge). We first clear the bit using the ~RISING value.
++ */
++ temp_reg = (registers[msp]->global_ctrl) & ~TX_CLK_POL_RISING;
++ temp_reg |=
++ msp_tx_clkpol_bit(protocol_desc_tab[protocol].
++ tx_clock_edge);
++ temp_reg |= TX_EXTRA_DELAY_ENABLE;
++ temp_reg |= msp_data_delay_bits(MSP_DELAY_1);
+
-+/*
-+ * epio
-+ */
-+#define EPIO_NAME "EPIO"
++ (registers[msp]->global_ctrl) = temp_reg;
++ break;
++ case MSP_RECEIVE_MODE:
++ rx_status[msp].phase_mode =
++ protocol_desc_tab[protocol].phase_mode;
+
-+#ifndef EPIO_DEBUG
-+#define EPIO_DEBUG 0
-+#endif
++ /* Use a temp for setup. Clear everything except the two non-mode
++ * dependent bits, then add back the bits for the selected protocol
++ */
++ temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
+
-+#define NMDK_DEBUG EPIO_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX EPIO_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++ temp_reg |=
++ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++ temp_reg |=
++ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_1);
++ temp_reg |=
++ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_2);
++ if (data_size == MSP_DATA_SIZE_DEFAULT) {
++ temp_reg |=
++ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_1);
++ temp_reg |=
++ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_2);
++ if (protocol_desc_tab[protocol].element_len_1 ==
++ protocol_desc_tab[protocol].element_len_2) {
++ msp_context[msp].actual_data_size =
++ protocol_desc_tab[protocol].element_len_1;
++ } else {
++ msp_context[msp].actual_data_size = data_size;
++ }
++ } else {
++ temp_reg |= msp_p1_elem_len_bits(data_size);
++ temp_reg |= msp_p2_elem_len_bits(data_size);
++ msp_context[msp].actual_data_size = data_size;
++ }
++ temp_reg |=
++ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
+
-+static spinlock_t epio_cob_ctl_read = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_cob_ctl_write = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_kp_read = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_kp_write = SPIN_LOCK_UNLOCKED;
++ (registers[msp]->rx_config) = temp_reg;
+
-+static unsigned long epio_lgcl_addr_cob_ident_reg;
-+static unsigned long epio_lgcl_addr_cob_ctl_reg;
-+static unsigned long epio_lgcl_addr_kp_reg;
-+static unsigned long epio_lgcl_addr_exp_ctrl_reg;
-+static spinlock_t epio_exp_ctrl_read = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_exp_ctrl_write = SPIN_LOCK_UNLOCKED;
++ /* The rx_config register is done, now set the clock mode (rising
++ * or falling edge). We first clear the bit using the ~RISING value.
++ */
++ temp_reg = (registers[msp]->global_ctrl) & ~RX_CLK_POL_RISING;
++ temp_reg |=
++ msp_rx_clkpol_bit(protocol_desc_tab[protocol].
++ rx_clock_edge);
+
-+/*
-+ * nomadik_epio_read_cob_ident - reads COB_IDENT register of CPLD
-+ *
-+ * Reads the core bord version and CPLD version information stored in
-+ * COB_IDENT register of CPLD on NDK10
-+ */
-+static short nomadik_epio_read_cob_ident(void)
-+{
-+ return ((short)
-+ *((volatile unsigned short *)epio_lgcl_addr_cob_ident_reg));
-+}
++ (registers[msp]->global_ctrl) = temp_reg;
++ break;
++ case MSP_BOTH_T_R_MODE:
++ rx_status[msp].phase_mode =
++ protocol_desc_tab[protocol].phase_mode;
++ tx_status[msp].phase_mode =
++ protocol_desc_tab[protocol].phase_mode;
+
-+/**
-+ * nomadik_epio_read_cob_ctl - reads COB_CTL register of CPLD
-+ *
-+ * Reads the present value of the core-board-configuration register of CPLD
-+ * on NDK10 board
-+ */
-+short nomadik_epio_read_cob_ctl(void)
-+{
-+ short i;
++ /* Use a temp for setup. Clear everything except the two non-mode
++ * dependent bits, then add back the bits for the selected protocol
++ * do rx_config first
++ */
++ temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
+
-+ spin_lock(&epio_cob_ctl_read);
-+ i = *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg);
-+ spin_unlock(&epio_cob_ctl_read);
-+ return (i);
-+}
++ temp_reg |=
++ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++ temp_reg |=
++ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_1);
++ temp_reg |=
++ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_2);
++ if (data_size == MSP_DATA_SIZE_DEFAULT) {
++ temp_reg |=
++ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_1);
++ temp_reg |=
++ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_2);
++ if (protocol_desc_tab[protocol].element_len_1 ==
++ protocol_desc_tab[protocol].element_len_2) {
++ msp_context[msp].actual_data_size =
++ protocol_desc_tab[protocol].element_len_1;
++ } else {
++ msp_context[msp].actual_data_size = data_size;
++ }
++ } else {
++ temp_reg |= msp_p1_elem_len_bits(data_size);
++ temp_reg |= msp_p2_elem_len_bits(data_size);
++ msp_context[msp].actual_data_size = data_size;
++ }
++ temp_reg |=
++ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
+
-+/**
-+ * nomadik_epio_write_cob_ctl - writes COB_CTL register of CPLD
-+ * @expctrlval: value to be written
-+ *
-+ * Write the provided 16bit value into the core-board-configuration register
-+ * of CPLD on NDK10 board
-+ */
-+void nomadik_epio_write_cob_ctl(unsigned short expctrlval)
-+{
-+ spin_lock(&epio_cob_ctl_write);
-+ *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg) = expctrlval;
-+ spin_unlock(&epio_cob_ctl_write);
-+}
++ (registers[msp]->rx_config) = temp_reg;
+
-+/**
-+ * nomadik_epio_read_keypad - reads KEYPAD register of CPLD
-+ *
-+ * Reads the present value of the keypad assignment register of CPLD on NDK10
-+ */
-+short nomadik_epio_read_keypad(void)
-+{
-+ short i;
++ /* Now tx_config */
++ temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
+
-+ spin_lock(&epio_kp_read);
-+ i = (0x07FF & *((volatile unsigned short *)epio_lgcl_addr_kp_reg));
-+ spin_unlock(&epio_kp_read);
-+ return (i);
-+}
++ temp_reg |=
++ msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++ temp_reg |=
++ msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_1);
++ temp_reg |=
++ msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++ frame_len_2);
++ if (data_size == MSP_DATA_SIZE_DEFAULT) {
++ temp_reg |=
++ msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_1);
++ temp_reg |=
++ msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++ element_len_2);
++ } else {
++ temp_reg |= msp_p1_elem_len_bits(data_size);
++ temp_reg |= msp_p2_elem_len_bits(data_size);
++ }
++ temp_reg |=
++ msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
+
-+/**
-+ * nomadik_epio_write_keypad - writes KEYPAD register of CPLD
-+ * @keypadval: value to be written
-+ *
-+ * Writes the provided value to the keypad assignment reg of CPLD on NDK10
-+ */
-+void nomadik_epio_write_keypad(unsigned short kpdval)
-+{
-+ unsigned short i;
++ (registers[msp]->tx_config) = temp_reg;
++ /* The [rt]x_config register is done, now set the clock mode (rising
++ * or falling edge). We first clear the bit using the ~RISING value.
++ */
++ temp_reg =
++ (registers[msp]->
++ global_ctrl) & ~(TX_CLK_POL_RISING | RX_CLK_POL_RISING);
++ temp_reg |=
++ msp_rx_clkpol_bit(protocol_desc_tab[protocol].
++ rx_clock_edge);
++ temp_reg |=
++ msp_tx_clkpol_bit(protocol_desc_tab[protocol].
++ tx_clock_edge);
+
-+ spin_lock(&epio_kp_write);
-+ i = *((volatile unsigned short *)epio_lgcl_addr_kp_reg);
-+ i &= 0xF800;
-+ i |= kpdval & 0x07ff;
-+ *((volatile unsigned short *)epio_lgcl_addr_kp_reg) = i;
-+ spin_unlock(&epio_kp_write);
-+}
++ (registers[msp]->global_ctrl) = temp_reg;
++ break;
++ default:
++ printk(KERN_ERR "Invalid direction given\n");
++ return -EINVAL;
++ }
+
-+/**
-+ * nomadik_epio_read_exp_ctrl - reads exp ctrl register of CPLD
-+ *
-+ * Reads the 16bit value of the expansion-board-control register of CPLD on NDK10
-+ */
-+short nomadik_epio_read_exp_ctrl(void)
-+{
-+ short i = 0;
-+ spin_lock(&epio_exp_ctrl_read);
-+ i = *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg);
-+ spin_unlock(&epio_exp_ctrl_read);
-+ return (i);
++ return 0;
+}
+
-+/**
-+ * nomadik_epio_write_exp_ctrl - writes exp ctrl register of CPLD
-+ * @expctrlval: value to be written
-+ *
-+ * Writes the provided 16bit value into the expansion-board-control register
-+ * of CPLD on NDK10
-+ */
-+void nomadik_epio_write_exp_ctrl(unsigned short expctrlval)
++static int configure_clock(int msp, int protocol, u32 input_clock,
++ u32 frame_freq, int frame_size)
+{
-+ spin_lock(&epio_exp_ctrl_write);
-+ *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg) = expctrlval;
-+ spin_unlock(&epio_exp_ctrl_write);
-+}
++ u32 dummy;
++ u32 frame_per = 0;
++ u32 sck_div = 0;
++ u32 frame_width = 0;
++ u32 temp_reg = 0;
++ u32 data_size;
+
-+/**
-+ * nomadik_epio_init - epio module init call.
-+ */
-+static int __init nomadik_epio_init(void)
-+{
-+ unsigned short i;
++ (registers[msp]->global_ctrl) &= ~SRG_ENABLE;
+
-+ nmdk_dbg_ftrace();
-+ epio_lgcl_addr_cob_ident_reg =
-+ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x000, (unsigned long)2);
-+ epio_lgcl_addr_cob_ctl_reg =
-+ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x002, (unsigned long)2);
-+ epio_lgcl_addr_kp_reg =
-+ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x004, (unsigned long)2);
-+ epio_lgcl_addr_exp_ctrl_reg =
-+ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x006, (unsigned long)2);
++ switch (msp_context[msp].actual_data_size) {
++ case MSP_DATA_SIZE_8BIT:
++ data_size = 8;
++ break;
++ case MSP_DATA_SIZE_10BIT:
++ data_size = 10;
++ break;
++ case MSP_DATA_SIZE_12BIT:
++ data_size = 12;
++ break;
++ case MSP_DATA_SIZE_14BIT:
++ data_size = 14;
++ break;
++ case MSP_DATA_SIZE_16BIT:
++ data_size = 16;
++ break;
++ case MSP_DATA_SIZE_20BIT:
++ data_size = 20;
++ break;
++ case MSP_DATA_SIZE_24BIT:
++ data_size = 24;
++ break;
++ case MSP_DATA_SIZE_32BIT:
++ data_size = 32;
++ break;
++ default:
++ printk(KERN_ERR
++ "Unable to determine data size in configure_clock\n");
++ return -EINVAL;
++ }
+
-+ i = nomadik_epio_read_cob_ident();
-+ nmdk_info("Core Board Revision %d.%d, CPLD Code Revision %d.%d",
-+ (i & COB_REV_BITS) >> COB_REV_BITS_POS,
-+ (i & COB_REV_SUBBITS) >> COB_REV_SUBBITS_POS,
-+ (i & CPLD_REV_BITS) >> CPLD_REV_BITS_POS,
-+ (i & CPLD_REV_SUBBITS));
-+ return 0;
-+}
-+#undef NMDK_DEBUG /*epio*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
++ switch (protocol) {
++ case MSP_PCM_PROTOCOL:
++ case MSP_PCM_COMPAND_PROTOCOL:
++ case MSP_MASTER_SPI_PROTOCOL:
++ if (frame_size < 0) {
++ frame_per = data_size;
++ if (protocol == MSP_MASTER_SPI_PROTOCOL) {
++ /* Need 1 clock between start of frame and start
++ * of data, and 1 clock to indicate end of frame
++ */
++ frame_per += 2;
++ }
++ } else {
++ frame_per = data_size;
++ }
++ if (frame_per < data_size) {
++ printk(KERN_ERR
++ "Frame size too small in configure_clock\n");
++ return -EINVAL;
++ }
++ frame_width = 1;
+
-+/*
-+ * board init
-+ */
-+#define BOARD_NAME CONFIG_NOMADIK_PLATFORM
-+#ifndef BOARD_DEBUG
-+#define BOARD_DEBUG 0
-+#endif
++ sck_div = input_clock / (frame_freq << 8);
++ frame_per = MSP_FRAME_PERIOD_IN_MONO_MODE;
+
-+#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++ break;
++ case MSP_I2S_PROTOCOL:
++ sck_div = input_clock / (frame_freq << 5);
++ frame_per = MSP_FRAME_PERIOD_IN_STEREO_MODE;
++ frame_width = MSP_FRAME_WIDTH_IN_STEREO_MODE;
+
-+void __init nomadik_pepperpot_board_init(void)
-+{
-+ int err;
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot |
-+ CAM_RSTnot);
-+ err = 0;
-+ while (err < 0xffffff)
-+ err++;
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000);
-+ err = 0;
-+ while (err < 0xffffff)
-+ err++;
-+}
++ break;
++ case MSP_AC97_PROTOCOL:
++ /* Not supported */
++ printk(KERN_WARNING "AC97 protocol not supported\n");
++ return -ENOSYS;
++ case MSP_SLAVE_SPI_PROTOCOL:
++ sck_div = 1;
++ break;
++ default:
++ printk(KERN_ERR "Invalid mode attempted for setting clocks\n");
++ return -EINVAL;
++ }
+
-+void __init nomadik_platform_board_init(void)
-+{
-+ unsigned char __iomem *gpio0_base;
-+ unsigned char __iomem *gpio1_base;
-+ unsigned char __iomem *cpld_base;
-+ unsigned char __iomem *rgpo1_base;
-+ unsigned char __iomem *pmu_base;
-+ unsigned char __iomem *base;
++ temp_reg = (sck_div - 1) & SCK_DIV_MASK;
++ temp_reg |= frame_width_bits(frame_width - 1);
++ temp_reg |= frame_period_bits(frame_per - 1);
++ registers[msp]->srg_ctrl = temp_reg;
+
-+ gpio0_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO0_BASE);
-+ gpio1_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO1_BASE);
++ /* Wait a bit */
++ dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
+
-+ rgpo1_base = (unsigned char *)IO_ADDRESS(NOMADIK_CPLD_RGPO1_BASE);
-+ cpld_base = ioremap(NOMADIK_CPLD_BASE, SZ_4K);
-+ base = ioremap(0x36400000, SZ_4K);
++ /* Enable clock */
++ registers[msp]->global_ctrl |= SRG_ENABLE;
+
-+ /*
-+ * Set Display control LCD*
-+ * Set bit 26 of pmu->ctrl register to 0. CLCD/DIF selection
-+ */
-+ pmu_base = (unsigned char *)IO_ADDRESS(NOMADIK_PMU_BASE);
-+ writel((0xFBBFFFFF & readl(pmu_base)), pmu_base);
++ /* Another wait */
++ dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
++ /* reconfigure spi clock mode */
++ temp_reg = registers[msp]->global_ctrl;
++ temp_reg &= ~SPI_CLK_MODE_MASK;
++ temp_reg |= spi_clock_mode[msp];
++ temp_reg &= ~SPI_BURST_MODE_MASK;
++ temp_reg |= spi_burst_mode[msp];
+
-+ /*
-+ * Enabling alt func A for gpio0-gpio7 :UART0
-+ */
-+ writel(0xff, gpio0_base + 0x20);
++ registers[msp]->global_ctrl = temp_reg;
++ return 0;
++}
+
-+ /*
-+ * Enabling alt func A for gpio51,52,56,57 :UART1
-+ */
-+ writel(0x3180000, gpio1_base + 0x20);
++static irqreturn_t handle_irq(int irq, void *dev_id)
++{
++ int msp;
++ u32 irq_status;
+
-+ /*
-+ * Enabling alt func B for gpio32-39
-+ */
-+ writel(0xff, gpio1_base + 0x24);
++ /* dev_id should be the register base address, find out which MSP
++ * we are dealing with. */
++ for (msp = 0; msp < MSP_COUNT; msp++) {
++ if (dev_id == registers[msp]) {
++ break;
++ }
++ }
+
-+ /*
-+ * Change in cpld register on cob10
-+ * UART1 trasnceiver enable, uart0 enable
-+ */
-+ writew((0x218 | (readw(cpld_base + 02) & ~(0x238))), (cpld_base + 02));
++ if (msp == MSP_COUNT) {
++ /* Didn't find the MSP, this must not be our interrupt */
++ return -1;
++ }
+
-+ /*
-+ * CPLD setting for pepperport camera poweron
-+ *
-+ */
-+ writew((0xc00 | readw(cpld_base + 02)), (cpld_base + 02));
++ irq_status = registers[msp]->masked_irq_status;
+
-+ /*
-+ * Setting as copied from CMM file (backlite disabled)
-+ */
-+ writew(0xc000, base);
-+ writew(0x900f, rgpo1_base);
-+ writew(0x53ff, cpld_base + 6);
-+ writew(0xdfff, rgpo1_base);
-+ writew(0x8001, rgpo1_base);
++ /* Disable the interrupt to prevent immediate recurrence */
++ registers[msp]->irq_mask &= ~irq_status;
+
-+ writew(readw(cpld_base + 0x6) | 0x1000, cpld_base + 6);
++ /* Clear the interrupt */
++ registers[msp]->irq_clear = irq_status;
+
-+ /*
-+ * Change in cpld uib register
-+ * Enable uart0
-+ */
-+ writew((0x8000 | readw(rgpo1_base)), rgpo1_base);
++ /* Check for an error condition */
++ msp_io_error[msp] |= irq_status & (RECEIVE_OVERRUN_ERROR_INT |
++ RECEIVE_FRAME_SYNC_ERR_INT |
++ TRANSMIT_UNDERRUN_ERR_INT |
++ TRANSMIT_FRAME_SYNC_ERR_INT);
++
++ /* Wake up the reader/writer */
++ wake_up_interruptible(&wait[msp]);
++ return IRQ_HANDLED;
+
-+ iounmap(cpld_base);
-+ iounmap(base);
-+ printk("%s done\n", __FUNCTION__);
+}
+
-+/**
-+ * nomadik_clcd_board_enable - enables board specific clcd prameters
-+ *
-+ * Settings to enable backlight and pannel voltage regulator for NDK10
-+ * bit 10 to set backlight on, bit 11 to set LCD power regulator on
-+ */
-+void nomadik_clcd_enable(void *fbp)
++static int transmit_data(int msp, void *data, size_t bytes)
+{
-+#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT)
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x0c00);
-+#endif
++ return transmit_receive_data(msp, tx_status[msp].work_mode,
++ data, bytes, NULL, 0);
+}
+
-+/**
-+ * nomadik_clcd_board_disable - disables board specific clcd prameters
-+ *
-+ * Settings to disable backlight and pannel voltage regulator for NDK10
-+ * bit 10 to reset backlight off, bit 11 to reset LCD power regulator off
-+ */
-+void nomadik_clcd_disable(void *fbp)
++static int receive_data(int msp, void *data, size_t bytes)
+{
-+#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT)
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & (~0x0c00));
-+#endif
++ return transmit_receive_data(msp, rx_status[msp].work_mode,
++ NULL, 0, data, bytes);
+}
+
-+/*
-+ * Settings to configure MMC controller for NDK10
-+ */
-+int nomadik_mmc_configure(struct amba_device *dev)
++static int transmit_receive_data(int msp, int work_mode,
++ void *txdata, size_t txbytes,
++ void *rxdata, size_t rxbytes)
+{
-+ int ret;
-+ gpio_config mmc_pin;
-+ char x = val_volt;
-+
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() |
-+ MASK_MMC_EPIO);
-+ mmc_pin.dev_name = "mmc";
-+ mmc_pin.mode = GPIO_MODE_SOFTWARE;
-+ mmc_pin.direction = GPIO_DIR_OUTPUT;
-+ mmc_pin.trig = GPIO_TRIG_DISABLE;
-+ mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
-+
-+ ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
-+ if (ret) {
-+ nmdk_error("Error in setting GPIO_PIN_75");
-+ goto exit_last;
-+ }
-+ /* this enables power path from toureg to mmc */
-+ ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, "mmc");
-+ if (ret) {
-+ nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
-+ goto deallocate_pin_75;
-+ }
++ int status;
++ u32 tx_offset = 0;
++ u32 rx_offset = 0;
++ u8 *data_src_8bit, *data_dst_8bit;
++ u16 *data_src_16bit, *data_dst_16bit;
++ u32 *data_src_32bit, *data_dst_32bit;
+
-+ ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
-+ if (ret) {
-+ nmdk_error("Error in writing value to touareg register");
-+ goto deallocate_pin_75;
++ if (txdata == NULL && txbytes > 0) {
++ printk(KERN_ERR
++ "transmit_receive_data received a NULL transmit buffer with bytes to transmit\n");
++ return -EINVAL;
+ }
+
-+ ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, "mmc");
-+ if (ret) {
-+ nmdk_error("Error in gpio Altfunction enable");
-+ goto deallocate_pin_75;
++ if (rxdata == NULL && rxbytes > 0) {
++ printk(KERN_ERR
++ "transmit_receive_data received a NULL receive buffer with bytes to receive\n");
++ return -EINVAL;
+ }
-+ return ret;
+
-+ deallocate_pin_75:
-+ nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc");
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
-+ ~MASK_MMC_EPIO);
-+ exit_last:
-+ return ret;
++ data_src_8bit = (u8 *) txdata;
++ data_src_16bit = (u16 *) txdata;
++ data_src_32bit = (u32 *) txdata;
+
-+}
++ data_dst_8bit = (u8 *) rxdata;
++ data_dst_16bit = (u16 *) rxdata;
++ data_dst_32bit = (u32 *) rxdata;
+
-+void nomadik_mmc_restore_default(struct amba_device *dev)
-+{
-+ nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, "mmc");
-+ nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc");
++ msp_io_error[msp] = 0;
+
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
-+ ~MASK_MMC_EPIO);
++ while (tx_offset < txbytes || rx_offset < rxbytes) {
++ if (msp_io_error[msp]) {
++ return -EIO;
++ }
++
++ if (rx_offset < rxbytes &&
++ !((registers[msp]->status) & RX_FIFO_EMPTY)) {
++ switch (msp_context[msp].actual_data_size) {
++ case MSP_DATA_SIZE_8BIT:
++ rx_offset += sizeof(*data_dst_8bit);
++ *data_dst_8bit++ = registers[msp]->fifo;
++ break;
++ case MSP_DATA_SIZE_10BIT:
++ case MSP_DATA_SIZE_12BIT:
++ case MSP_DATA_SIZE_14BIT:
++ case MSP_DATA_SIZE_16BIT:
++ rx_offset += sizeof(*data_dst_16bit);
++ *data_dst_16bit++ = registers[msp]->fifo;
++ break;
++ case MSP_DATA_SIZE_20BIT:
++ case MSP_DATA_SIZE_24BIT:
++ case MSP_DATA_SIZE_32BIT:
++ rx_offset += sizeof(*data_dst_32bit);
++ *data_dst_32bit++ = registers[msp]->fifo;
++ break;
++ default:
++ printk(KERN_ERR
++ "Unable to determine data size in transmit_receive_data\n");
++ return -EIO;
++ }
++ }
++
++ if (tx_offset < txbytes &&
++ !((registers[msp]->status) & TX_FIFO_FULL)) {
++ switch (msp_context[msp].actual_data_size) {
++ case MSP_DATA_SIZE_8BIT:
++ tx_offset += sizeof(*data_src_8bit);
++ registers[msp]->fifo = *data_src_8bit++;
++ break;
++ case MSP_DATA_SIZE_10BIT:
++ case MSP_DATA_SIZE_12BIT:
++ case MSP_DATA_SIZE_14BIT:
++ case MSP_DATA_SIZE_16BIT:
++ tx_offset += sizeof(*data_src_16bit);
++ registers[msp]->fifo = *data_src_16bit++;
++ break;
++ case MSP_DATA_SIZE_20BIT:
++ case MSP_DATA_SIZE_24BIT:
++ case MSP_DATA_SIZE_32BIT:
++ tx_offset += sizeof(*data_src_32bit);
++ registers[msp]->fifo = *data_src_32bit++;
++ break;
++ default:
++ printk(KERN_ERR
++ "Unable to determine data size in transmit_receive_data\n");
++ return -EIO;
++ }
++ }
++
++ if (work_mode == MSP_INTERRUPT_MODE &&
++ (tx_offset < txbytes || rx_offset < rxbytes)) {
++ u32 status_mask = 0;
++ u32 irq_mask = 0;
++ if (tx_offset < txbytes) {
++ status_mask |= TX_FIFO_FULL;
++ irq_mask |= TRANSMIT_SERVICE_INT;
++ if (!(registers[msp]->status & TX_FIFO_FULL)) {
++ continue;
++ }
++ }
++ if (rx_offset < rxbytes) {
++ status_mask |= RX_FIFO_EMPTY;
++ irq_mask |= RECEIVE_SERVICE_INT;
++ if (!(registers[msp]->status & RX_FIFO_EMPTY)) {
++ continue;
++ }
++ }
++ registers[msp]->irq_mask |= irq_mask;
++ status = wait_event_interruptible(wait[msp],
++ !(registers[msp]->
++ status &
++ status_mask)
++ && msp_io_error[msp]
++ == 0);
++ if (status) {
++ return status;
++ }
++ }
++ }
++
++ return txbytes + rxbytes;
+}
+
-+/*
-+ * nomadik_fsmc_init - fsmc initialization on system start
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++
++/**
++ * msp_controller_cmd - To execute controller specific commands for MSP
++ * @drv_data: SPI driver private data structure
++ * @cmd: Command which is to be executed on the controller
++ *
++ *
+ */
-+static __init void nomadik_fsmc_init(void)
++static int msp_controller_cmd(struct driver_data *drv_data, int cmd)
+{
-+ unsigned char __iomem *fsmc_base;
-+
++ int retval = 0;
+ nmdk_dbg_ftrace();
-+ /*Following Settings done for NAND flash protect off */
-+ fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
++ switch (cmd)
++ {
++ case DISABLE_CONTROLLER:
++ {
++ nmdk_dbg2(":::: DISABLE_CONTROLLER\n");
++ writel((readl(MSP_GCR(drv_data->regs)) & (~(MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN ))), MSP_GCR(drv_data->regs));
++ break;
++ }
++ case ENABLE_CONTROLLER:
++ {
++ nmdk_dbg2(":::: ENABLE_CONTROLLER\n");
++ writel((readl(MSP_GCR(drv_data->regs)) | (MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN )), MSP_GCR(drv_data->regs));
++ break;
++ }
++ case DISABLE_DMA:
++ {
++ nmdk_dbg2(":::: DISABLE_DMA\n");
++ writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
++ break;
++ }
++ case ENABLE_DMA:
++ {
++ nmdk_dbg2(":::: ENABLE_DMA\n");
++ writel(drv_data->cur_chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
++ break;
++ }
++ case DISABLE_ALL_INTERRUPT:
++ {
++ nmdk_dbg2(":::: DISABLE_ALL_INTERRUPT\n");
++ writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++ break;
++ }
++ case ENABLE_ALL_INTERRUPT:
++ {
++ nmdk_dbg2(":::: ENABLE_ALL_INTERRUPT\n");
++ writel( ENABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++ break;
++ }
++ case CLEAR_ALL_INTERRUPT:
++ {
++ nmdk_dbg2(":::: CLEAR_ALL_INTERRUPT\n");
++ writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
++ break;
++ }
++ case FLUSH_FIFO:
++ {
++ unsigned long limit = loops_per_jiffy << 1;
++ nmdk_dbg2(":::: DATA FIFO is flushed\n");
++ do {
++ while( ! (readl(MSP_FLR(drv_data->regs)) & MSP_FLR_MASK_RFE))
++ readl(MSP_DR(drv_data->regs));
++ } while ((readl(MSP_FLR(drv_data->regs)) & (MSP_FLR_MASK_TBUSY | MSP_FLR_MASK_RBUSY)) && limit--);
++ retval = limit;
++ break;
++ }
++ case RESTORE_STATE:
++ {
++ struct chip_data *chip = drv_data->cur_chip;
++ nmdk_dbg2(":::: RESTORE_STATE\n");
++ writel(chip->regs.mspr.gcr, MSP_GCR(drv_data->regs));
++ writel(chip->regs.mspr.tcf, MSP_TCF(drv_data->regs));
++ writel(chip->regs.mspr.rcf, MSP_RCF(drv_data->regs));
++ writel(chip->regs.mspr.srg, MSP_SRG(drv_data->regs));
++ writel(chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
++ writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++ writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
++ break;
++ }
++ case LOAD_DEFAULT_CONFIG:
++ {
++ nmdk_dbg2(":::: LOAD_DEFAULT_CONFIG\n");
++ writel(DEFAULT_MSP_REG_GCR, MSP_GCR(drv_data->regs));
++ writel(DEFAULT_MSP_REG_TCF, MSP_TCF(drv_data->regs));
++ writel(DEFAULT_MSP_REG_RCF, MSP_RCF(drv_data->regs));
++ writel(DEFAULT_MSP_REG_SRG, MSP_SRG(drv_data->regs));
++ writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
++ writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++ writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
++ break;
++ }
++ default:
++ {
++ nmdk_dbg2(":::: unknown command\n");
++ retval = -1;
++ break;
++ }
++ }
++ return retval;
++}
+
-+ /* for NOR accesss */
-+ /* Initialize the fsmc bank 0 */
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
-+ /* Initialize the fsmc bank 1 */
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db;
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702;
++void msp_u8_writer(struct driver_data *drv_data)
++{
++ u32 cur_write = 0;
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
++ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++ return;
++ writel((u32) (*(u8 *) (drv_data->tx)), MSP_DR(drv_data->regs));
++ drv_data->tx += (drv_data->cur_chip->n_bytes);
++ cur_write ++;
++ if(cur_write == 8)
++ return;
++ }
++}
++void msp_u8_reader(struct driver_data *drv_data)
++{
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
++ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++ return;
++ *(u8 *) (drv_data->rx) = (u8) readl(MSP_DR(drv_data->regs));
++ drv_data->rx += (drv_data->cur_chip->n_bytes);
++ }
++}
++void msp_u16_writer(struct driver_data *drv_data)
++{
++ u32 cur_write = 0;
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
+
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
-+ /* Above Settings done for NAND flash protect off */
++ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++ return;
++ writel((u32) (*(u16 *) (drv_data->tx)), MSP_DR(drv_data->regs));
++ drv_data->tx += (drv_data->cur_chip->n_bytes);
++ cur_write ++;
++ if(cur_write == 8)
++ return;
++ }
++}
++void msp_u16_reader(struct driver_data *drv_data)
++{
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
++ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++ return;
++ *(u16 *) (drv_data->rx) = (u16) readl(MSP_DR(drv_data->regs));
++ drv_data->rx += (drv_data->cur_chip->n_bytes);
++ }
+}
+
-+int nomadik_pepperpot_init(void)
++void msp_u32_writer(struct driver_data *drv_data)
+{
-+ int err;
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot |
-+ CAM_RSTnot);
-+ err = 0;
-+ while (err < 0xffffff)
-+ err++;
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000);
-+ err = 0;
-+ while (err < 0xffffff)
-+ err++;
++ u32 cur_write = 0;
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
+
-+ return 0;
++ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++ return;
++ /*Write Data to Data Register */
++ writel(*(u32 *) (drv_data->tx), MSP_DR(drv_data->regs));
++ drv_data->tx += (drv_data->cur_chip->n_bytes);
++ cur_write ++;
++ if(cur_write == 8)
++ return;
++ }
++}
++void msp_u32_reader(struct driver_data *drv_data)
++{
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
++ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++ return;
++ *(u32 *) (drv_data->rx) = readl(MSP_DR(drv_data->regs));
++ drv_data->rx += (drv_data->cur_chip->n_bytes);
++ }
+}
+
-+EXPORT_SYMBOL(nomadik_pepperpot_init);
++static irqreturn_t nomadik_msp_interrupt_handler(int irq, void *dev_id)
++{
++ struct driver_data *drv_data = (struct driver_data *)dev_id;
++ struct spi_message *msg = drv_data->cur_msg;
++ u32 irq_status = 0;
++ u32 flag = 0;
++ if (!msg) {
++ dev_err(&drv_data->adev->dev,
++ "bad message state in interrupt handler");
++ /* Never fail */
++ return IRQ_HANDLED;
++ }
++ /*Read the Interrupt Status Register */
++ irq_status = readl(MSP_MIS(drv_data->regs));
+
-+#ifdef CONFIG_MTD
++ if (irq_status) {
++ if (irq_status & MSP_MIS_MASK_ROEMIS) { /*Overrun interrupt */
++ /*Bail-out our Data has been corrupted */
++ nmdk_dbg3(":::: Received ROR interrupt\n");
++ drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
++ drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
++ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++ msg->state = ERROR_STATE;
++ tasklet_schedule(&drv_data->pump_transfers);
++ return IRQ_HANDLED;
++ }
+
-+static struct resource nandflash_resources[] = {
-+ [0] = {
-+ .name = "cmem_address",
-+ .start = NAND_B0_CMEM_ADDR,
-+ .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .name = "cmem_command",
-+ .start = NAND_B0_CMEM_CMD,
-+ .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [2] = {
-+ .name = "cmem_data",
-+ .start = NAND_B0_CMEM_DATA,
-+ .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+};
++ drv_data->read(drv_data);
++ drv_data->write(drv_data);
+
-+#define NAND_STM_LP_OPTIONS \
-+ (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
++ if ((drv_data->tx == drv_data->tx_end) && (flag == 0)) {
++ flag = 1;
++ /*Disable Transmit interrupt */
++ writel(readl(MSP_IMSC(drv_data->regs)) & (~MSP_IMSC_MASK_TXIM) & (~MSP_IMSC_MASK_TFOIM), (drv_data->regs + 0x14));
++ }
++ /*Clearing any Transmit underrun error. overrun already handled*/
++ drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
+
-+int nomadik_nandflash_exit(void)
-+{
-+ if(nomadik_gpio_resetpinconfig(NAND_GPIO, "nand"))
-+ return -1;
-+ return 0;
++ if (drv_data->rx == drv_data->rx_end) {
++ drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
++ drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
++ nmdk_dbg3(":::: Interrupt transfer Completed...\n");
++ /* Update total bytes transfered */
++ msg->actual_length += drv_data->cur_transfer->len;
++ if (drv_data->cur_transfer->cs_change)
++ drv_data->cur_chip->
++ cs_control(SPI_CHIP_DESELECT);
++ /* Move to next transfer */
++ msg->state = next_transfer(drv_data);
++ tasklet_schedule(&drv_data->pump_transfers);
++ return IRQ_HANDLED;
++ }
++ }
++ return IRQ_HANDLED;
+}
+
-+void nomadik_nandflash_init(void)
++static int verify_msp_controller_parameters(struct nmdk_spi_config_chip *chip_info)
+{
-+ /*
-+ * FSMC initialization
-+ * 0x0000001e => PCR0
-+ * 0x000d0a00 => PMEM0
-+ * 0x00100a00 => PATT0
-+ */
-+
-+/* pcr0.address_low = 0;*/
-+ gpio_config nmdknand_pin_config;
-+ nmdknand_pin_config.dev_name = "nand";
-+ nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
-+ nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
-+ nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
-+ nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+ if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config))
-+ return -1;
-+ if(nomadik_gpio_writepin(NAND_GPIO, 1, "nand"))
++ nmdk_dbg_ftrace();
++ /*FIXME: check clock params*/
++ if ((chip_info->lbm != LOOPBACK_ENABLED)
++ && (chip_info->lbm != LOOPBACK_DISABLED)) {
++ nmdk_dbg(":::: Loopback Mode is configured incorrectly\n");
+ return -1;
-+
-+
-+ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
-+ DEFAULT_PCR0_VALUE;
-+ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
-+ DEFAULT_PMEM0_VALUE;
-+ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
-+ DEFAULT_PATT0_VALUE;
++ }
++ if (chip_info->iface != SPI_INTERFACE_MOTOROLA_SPI){
++ nmdk_dbg(":::: Interface is configured incorrectly. This controller supports only MOTOROLA SPI\n");
++ return -1;
++ }
++ if ((chip_info->hierarchy != SPI_MASTER)
++ && (chip_info->hierarchy != SPI_SLAVE)) {
++ nmdk_dbg(":::: hierarchy is configured incorrectly\n");
++ return -1;
++ }
++ if ((chip_info->endian_rx != SPI_FIFO_MSB)
++ && (chip_info->endian_rx != SPI_FIFO_LSB)) {
++ nmdk_dbg(":::: Rx FIFO endianess is configured incorrectly\n");
++ return -1;
++ }
++ if ((chip_info->endian_tx != SPI_FIFO_MSB)
++ && (chip_info->endian_tx != SPI_FIFO_LSB)) {
++ nmdk_dbg(":::: Tx FIFO endianess is configured incorrectly\n");
++ return -1;
++ }
++ if (((chip_info->controller).msp.data_size < MSP_DATA_BITS_8) || ((chip_info->controller).msp.data_size > MSP_DATA_BITS_32)) {
++ nmdk_dbg(":::: MSP DATA Size is configured incorrectly\n");
++ return -1;
++ }
++ if ((chip_info->com_mode != INTERRUPT_TRANSFER)
++ && (chip_info->com_mode != DMA_TRANSFER)
++ && (chip_info->com_mode != POLLING_TRANSFER)) {
++ nmdk_dbg(":::: Communication mode is configured incorrectly\n");
++ return -1;
++ }
++ if (chip_info->iface == SPI_INTERFACE_MOTOROLA_SPI) {
++ if (((chip_info->proto_params).moto.clk_phase != SPI_CLK_ZERO_CYCLE_DELAY)
++ && ((chip_info->proto_params).moto.clk_phase != SPI_CLK_HALF_CYCLE_DELAY)) {
++ nmdk_dbg(":::: Clock Phase is configured incorrectly\n");
++ return -1;
++ }
++ if (((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_LOW)
++ && ((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_HIGH)) {
++ nmdk_dbg(":::: Clock Polarity is configured incorrectly\n");
++ return -1;
++ }
++ }
++ if (chip_info->cs_control == NULL) {
++ nmdk_dbg("::::Chip Select Function is NULL for this chip\n");
++ chip_info->cs_control = null_cs_control;
++ }
+ return 0;
+}
+
-+static const unsigned char lookup_t[256] = {
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
-+};
++/**
++ * nomadik_msp_setup - setup function registered to SPI master framework
++ * @spi: spi device which is requesting setup
++ *
++ * This function is registered to the SPI framework for this SPI master
++ * controller. If it is the first time when setup is called by this device
++ * , this function will initialize the runtime state for this chip and save
++ * the same in the device structure. Else it will update the runtime info
++ * with the updated chip info.
++ */
+
-+int nmdknand_compute_ecc512(struct mtd_info *mtd, unsigned char *data,
-+ unsigned char ecc[3])
++static int nomadik_msp_setup(struct spi_device *spi)
+{
-+ unsigned int sumCol = 0;
-+ unsigned int datum, temp;
-+ unsigned int glob_parity;
-+ const int ecc_n_bytes = 512;
-+ int i;
-+
-+ unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
-+ unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
-+ 0, parit32_1 = 0, parit32_2 = 0;
-+ unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
-+ 0, parit256_1 = 0, parit256_2 = 0;
-+ unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
-+ 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++ struct nmdk_spi_config_chip *chip_info;
++ struct chip_data *chip;
++ struct spi_master *master;
++ int status = 0;
++ u16 sckdiv = 0;
++ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++ nmdk_dbg_ftrace();
++ master = drv_data->master;
+
-+ for (i = ecc_n_bytes - 1; i >= 0; --i) {
-+ datum = data[i];
-+ sumCol ^= datum;
-+ temp = lookup_t[datum];
++ switch(master->bus_num) {
++ case MSP_0_CONTROLLER:
++ if((drv_data->flag_msp0->user != MSP_NO_USER) && (drv_data->flag_msp0->user != MSP_USER_SPI)){
++ status = -EINVAL;
++ printk(KERN_ERR "MSP0 already in use in %d mode", drv_data->flag_msp0->user);
++ }
++ else {
++ down(&drv_data->flag_msp0->lock);
++ drv_data->flag_msp0->user = MSP_USER_SPI;
++ up(&drv_data->flag_msp0->lock);
++ nmdk_dbg("Flag set to MSP_USER_SPI for MSP0\n");
++ }
++ break;
++ case MSP_1_CONTROLLER:
++ if((drv_data->flag_msp1->user != MSP_NO_USER) && (drv_data->flag_msp1->user != MSP_USER_SPI)){
++ status = -EINVAL;
++ printk(KERN_ERR "MSP1 already in use in %d mode", drv_data->flag_msp1->user);
++ }
++ else {
++ down(&drv_data->flag_msp1->lock);
++ drv_data->flag_msp1->user = MSP_USER_SPI;
++ up(&drv_data->flag_msp1->lock);
++ nmdk_dbg("Flag set to MSP_USER_SPI for MSP1\n");
++ }
++ break;
++ case MSP_2_CONTROLLER:
++ if((drv_data->flag_msp2->user != MSP_NO_USER) && (drv_data->flag_msp2->user != MSP_USER_SPI)){
++ status = -EINVAL;
++ printk(KERN_ERR "MSP2 already in use in %d mode", drv_data->flag_msp2->user);
++ }
++ else {
++ down(&drv_data->flag_msp2->lock);
++ drv_data->flag_msp2->user = MSP_USER_SPI;
++ up(&drv_data->flag_msp2->lock);
++ nmdk_dbg("Flag set to MSP_USER_SPI for MSP2\n");
++ }
++ break;
++ }
++ if(status)
++ return status;
+
-+ if (i & 0x01)
-+ parit8_1 ^= temp;
-+ if (i & 0x02)
-+ parit16_1 ^= temp;
-+ if (i & 0x04)
-+ parit32_1 ^= temp;
-+ if (i & 0x08)
-+ parit64_1 ^= temp;
-+ if (i & 0x10)
-+ parit128_1 ^= temp;
-+ if (i & 0x20)
-+ parit256_1 ^= temp;
-+ if (i & 0x40)
-+ parit512_1 ^= temp;
-+ if (i & 0x80)
-+ parit1024_1 ^= temp;
-+ if (i & 0x100)
-+ parit2048_1 ^= temp;
++ status = nomadik_gpio_altfuncenable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
++ if (status < 0) {
++ dev_err(&drv_data->adev->dev, "probe - unable to set GPIO Altfunc, %d\n", drv_data->master_info->gpio_alt_func);
++ status = -ENODEV;
++ goto err_out;
+ }
+
-+ glob_parity = lookup_t[sumCol];
++ status = request_irq(drv_data->adev->irq[0], nomadik_msp_interrupt_handler, 0, drv_data->master_info->device_name , drv_data);
++ if (status < 0) {
++ dev_err(&drv_data->adev->dev, "probe - cannot get IRQ (%d)\n", status);
++ goto err_altfunc_enable;
++ }
+
-+ parit1_1 =
-+ ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
-+ parit1_2 =
-+ ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
-+ parit2_1 =
-+ ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+ parit2_2 =
-+ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
-+ parit4_1 =
-+ ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+ parit4_2 =
-+ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++ /* Get controller data */
++ chip_info = spi->controller_data;
++ /* Get controller_state */
++ chip = spi_get_ctldata(spi);
++ if (chip == NULL) {
++ chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
++ if (!chip) {
++ dev_err(&spi->dev,
++ "setup - cannot allocate controller state");
++ goto err_request_irq;
++ }
++ chip->chip_id = spi->chip_select;
+
-+ parit8_2 = glob_parity ^ parit8_1;
-+ parit16_2 = glob_parity ^ parit16_1;
-+ parit32_2 = glob_parity ^ parit32_1;
-+ parit64_2 = glob_parity ^ parit64_1;
-+ parit128_2 = glob_parity ^ parit128_1;
-+ parit256_2 = glob_parity ^ parit256_1;
-+ parit512_2 = glob_parity ^ parit512_1;
-+ parit1024_2 = glob_parity ^ parit1024_1;
-+ parit2048_2 = glob_parity ^ parit2048_1;
++ nmdk_dbg(":::: chip Id for this client = %d\n", chip->chip_id);
++ nmdk_dbg(":::: Allocated Memory for controller's runtime state\n");
+
-+ /* Pack bits */
-+ ecc[0] =
-+ ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
-+ (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
-+ << 1) |
-+ parit8_2);
-+ ecc[1] =
-+ ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
-+ (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
-+ (parit128_1 << 1) | parit128_2);
-+ ecc[2] =
-+ ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
-+ (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
-+ << 1) |
-+ parit2048_2);
++ if (chip_info == NULL) {
++ /* spi_board_info.controller_data not is supplied */
++ chip_info =
++ kzalloc(sizeof(struct nmdk_spi_config_chip), GFP_KERNEL);
++ if (!chip_info) {
++ dev_err(&spi->dev,
++ "setup - cannot allocate controller data");
++ status = -ENOMEM;
++ goto err_first_setup;
++ }
++ nmdk_dbg(":::: Allocated Memory for controller data\n");
+
-+ return 0;
-+}
++ /* FIXME: Set controller data default value for MSP*/
++ chip_info->lbm = LOOPBACK_DISABLED;
++ chip_info->com_mode = POLLING_TRANSFER;
++ chip_info->iface = SPI_INTERFACE_MOTOROLA_SPI;
++ chip_info->hierarchy = SPI_MASTER;
++ chip_info->endian_tx = SPI_FIFO_LSB;
++ chip_info->endian_rx = SPI_FIFO_LSB;
++ (chip_info->controller).msp.data_size = MSP_DATA_BITS_32;
+
-+static struct nand_ecclayout nand_oob = {
-+ .eccbytes = 6,
-+ .eccpos = {2, 3, 4, 5, 6, 7},
-+ .oobavail = MTD_NANDECC_AUTOPLACE,
-+ .oobfree = {
-+ { .offset = 8,
-+ .length = 8,
-+ },
-+ },
-+};
++ if(spi->max_speed_hz != 0)
++ chip_info->freq = spi->max_speed_hz;
++ else
++ chip_info->freq = 48000;
+
-+#ifdef CONFIG_NOMADIK_NDK10_CUT_B06
-+static struct mtd_partition nandflash_main_partitions[] = {
++ (chip_info->proto_params).moto.clk_phase = SPI_CLK_HALF_CYCLE_DELAY;
++ (chip_info->proto_params).moto.clk_pol = SPI_CLK_POL_IDLE_LOW;
++ chip_info->cs_control = null_cs_control;
++ }
++ }
+
-+ {.name = "X-Loader(NAND)",
-+ .offset = 0,
-+ .size = 2 * 0x000020000}, /*256 Kbytes */
-+ {.name = "MemInit(NAND)",
-+ .offset = 2 * 0x000020000,
-+ .size = 2 * 0x000020000}, /*128 KBytes */
-+ {.name = "BootLoader(NAND)",
-+ .offset = 4 * 0x000020000,
-+ .size = 16 * 0x00020000}, /*2Mbytes */
-+ {.name = "Kernel zImage(NAND)",
-+ .offset = 20 * 0x000020000,
-+ .size = 24 * 0x000020000}, /*3Mbytes */
-+ {.name = "Root Filesystem(NAND)",
-+ .offset = 44 * 0x000020000,
-+ .size = 176 * 0x000020000}, /*22 Mbytes */
-+ {.name = "User Filesystem(NAND)",
-+ .offset = 220 * 0x000020000,
-+ .size = 800 * 0x000020000}, /*100 Mbytes */
-+};
-+#else
-+static const struct mtd_partition nandflash_main_partitions[] = {
-+ {.name = "X-Loader(NAND)",
-+ .offset = 0,
-+ .size = 4 * 0x00004000},
-+ {.name = "MemInit(NAND)",
-+ .offset = 4 * 0x00004000,
-+ .size = 1 * 0x00004000},
-+ {.name = "BootLoader(NAND)",
-+ .offset = 5 * 0x00004000,
-+ .size = 16 * 0x0004000},
-+ {.name = "Kernel zImage(NAND)",
-+ .offset = 21 * 0x00004000,
-+ .size = 3 * 0x00100000},
-+ {.name = "Root Filesystem(NAND)",
-+ .offset = 0x354000,
-+ .size = 0x0a00000},
-+ {.name = "User Filesystem(NAND)",
-+ .offset = 0xd54000,
-+ .size = 0x12aC000},
-+};
++ if(chip_info->freq == 0){
++ /*Calculate Specific Freq.*/
++ if ( (MSP_INTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)
++ || ( MSP_EXTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)){
++ sckdiv = (chip_info->controller).msp.clk_freq.sckdiv;
+
-+#endif
++ }else{
++ status = -1;
++ dev_err(&spi->dev, "setup - controller clock data is incorrect");
++ goto err_config_params;
++ }
++ }else{
++ /*Calculate Effective Freq.*/
++ sckdiv =((DEFAULT_MSP_CLK) / (chip_info->freq)) - 1;
++ if(sckdiv > MAX_SCKDIV){
++ printk("SPI: Cannot set frequency less than 48Khz, setting lowest(48 Khz)\n");
++ sckdiv = MAX_SCKDIV;
++ }
++ }
+
-+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
-+static struct nand_bbt_descr bbt_desc = {
-+ .options = 0,
-+ .offs = 0,
-+ .len = 2,
-+ .pattern = scan_ff_pattern
-+};
++ status = verify_msp_controller_parameters(chip_info);
++ if (status) {
++ dev_err(&spi->dev, "setup - controller data is incorrect");
++ goto err_config_params;
++ }
+
-+static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
-+ unsigned int ctrl)
-+{
-+ struct nomadik_nand_info *drvdata =
-+ container_of(mtd, struct nomadik_nand_info, mtd);
++ /* Now set controller state based on controller data */
++ chip->xfer_type = chip_info->com_mode;
++ chip->cs_control = chip_info->cs_control;
+
-+ if (cmd == NAND_CMD_NONE)
-+ return;
+
-+ if (ctrl & NAND_NCE) {
-+ *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
-+ 0x40)) |= 0x04;
-+ }
-+ if (ctrl & NAND_CLE) {
-+ writeb(cmd,drvdata->cmemc_va);
-+ }
-+ if (ctrl & NAND_ALE) {
-+ writeb(cmd,drvdata->cmema_va);
++ /*FIXME: write all 8 & 16 bit functions*/
++ if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_8) {
++ nmdk_dbg(":::: Less than 8 bits per word....\n");
++ chip->n_bytes = 1;
++ chip->read = msp_u8_reader;
++ chip->write = msp_u8_writer;
++ } else if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_16) {
++ nmdk_dbg(":::: Less than 16 bits per word....\n");
++ chip->n_bytes = 2;
++ chip->read = msp_u16_reader;
++ chip->write = msp_u16_writer;
++ } else {
++ nmdk_dbg(":::: Less than 32 bits per word....\n");
++ chip->n_bytes = 4;
++ chip->read = msp_u32_reader;
++ chip->write = msp_u32_writer;
+ }
-+}
-+
-+static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
-+ .parts = nandflash_main_partitions,
-+ .num_parts = ARRAY_SIZE(nandflash_main_partitions),
-+ .lp_options = NAND_STM_LP_OPTIONS,
-+ .eccsize = 512,
-+ .eccsteps = 1,
-+ .badblockpos = 1,
-+ .init = nomadik_nandflash_init,
-+ .exit = nomadik_nandflash_exit,
-+ .nand_oob = &nand_oob,
-+ .bbt_desc = &bbt_desc,
-+ .compute_ecc = nmdknand_compute_ecc512,
-+ .hwcontrol = nmdknand_hwcontrol,
-+};
-+
-+static struct platform_device nomadik_nand_flash = {
-+ .name = "NOMADIK-NAND",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &nomadik_nand_flash_data,
-+ },
-+ .num_resources = ARRAY_SIZE(nandflash_resources),
-+ .resource = nandflash_resources,
-+};
+
-+static struct mtd_partition nmdkflash_main_partitions[] = {
-+ {.name = "BootLoader(NOR)",
-+ .size = 0x00040000, /*256K */
-+ .offset = 0,},
-+ {.name = "Kernel zImage(NOR)",
-+ .size = 0x001C0000, /*1.75MB */
-+ .offset = MTDPART_OFS_APPEND,},
-+ {.name = "Root Filesystem(NOR)",
-+ .size = 0x01200000, /*18MB */
-+ .offset = MTDPART_OFS_APPEND,},
-+ {.name = "User Filesystem(NOR)",
-+ .size = 0x00800000, /*8MB */
-+ .offset = MTDPART_OFS_APPEND,},
-+ {.name = "initrd(NOR)",
-+ .size = 0x00200000, /*4MB */
-+ .offset = MTDPART_OFS_APPEND,}
-+};
++ /*Now Initialize all register settings reqd. for this chip */
+
-+static struct flash_platform_data nomadik_nor_flash_data = {
-+ .name = "nomadik_nor",
-+ .map_name = "cfi_probe",
-+ //.width = NMDK_FLASH_BUSWIDTH,
-+ .parts = nmdkflash_main_partitions,
-+ .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
-+};
++ chip->regs.mspr.gcr = 0x0;
++ chip->regs.mspr.tcf = 0x0;
++ chip->regs.mspr.rcf = 0x0;
++ chip->regs.mspr.srg = 0x0;
++ chip->regs.mspr.dmacr = 0x0;
+
-+static struct resource norflash_resources[] = {
-+ [0] = {
-+ .name = "norflash-regs",
-+ .start = NMDK_FLASH_BASE,
-+ .end = (NMDK_FLASH_BASE + SZ_16M - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .name = "norflash-regs",
-+ .start = NMDK_FLASH_BASE + SZ_16M,
-+ .end = (NMDK_FLASH_BASE + SZ_32M - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+};
++ if ((chip_info->com_mode == DMA_TRANSFER)
++ && ((drv_data->master_info)->enable_dma)) {
++ chip->enable_dma = 1;
++ chip->dma_info = kzalloc(sizeof(struct spi_dma_info), GFP_KERNEL);
++ if(!chip->dma_info){
++ nmdk_dbg("Could not allocate memory for dma info of chip_data\n");
++ goto err_first_setup;
++ }
++ chip->dma_info->dma_xfer_type = chip_info->dma_xfer_type;
++ nmdk_dbg(":::: DMA mode set in controller state\n");
++ status = process_dma_info(chip_info, chip, (void *)drv_data);
++ if (status < 0)
++ goto err_config_params;
++ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_RDMAE, 0);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_TDMAE, 1);
+
-+static struct platform_device nomadik_nor_flash = {
-+ .name = "NOMADIK-NOR",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &nomadik_nor_flash_data,
-+ },
-+ .num_resources = ARRAY_SIZE(norflash_resources),
-+ .resource = norflash_resources,
-+};
++ /* find and request free dma chanel */
++ chip->dma_info->rx_dmach = request_available_dma(&(chip->dma_info->rx_dma_info));
++ if (chip->dma_info->rx_dmach < 0) {
++ nmdk_dbg(":::: Rx pipe request Failed: %d\n", chip->dma_info->rx_dmach);
++ goto err_rx_dmach_request;
++ }
++ nmdk_dbg(":::: Rx pipe Allocated = %d\n", chip->dma_info->rx_dmach);
+
-+#endif
++ status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->rx_dmach),
++ spi_dma_callback_handler, 0, 0,
++ (void *)drv_data);
++ if (status) {
++ nmdk_error("Error requesting rx callback dmach intr handler %d", status);
++ goto err_rx_clbk_request;
++ }
+
-+static void nomadik_smc91x_irq_init(void)
-+{
-+ int err;
-+ gpio_config smx91x_clkpin;
++ /* find and request free dma chanel */
++ chip->dma_info->tx_dmach = request_available_dma(&(chip->dma_info->tx_dma_info));
++ if (chip->dma_info->tx_dmach < 0) {
++ nmdk_dbg(":::: Tx pipe request Failed: %d\n", status);
++ goto err_tx_dmach_request;
++ }
++ nmdk_dbg(":::: Tx pipe Allocated = %d\n", chip->dma_info->tx_dmach);
+
-+ smx91x_clkpin.dev_name = "smc91x";
-+ smx91x_clkpin.mode = GPIO_ALTF_A;
-+ err = nomadik_gpio_setpinconfig(GPIO_PIN_55, &smx91x_clkpin);
-+ if (err) {
-+ nmdk_error("Error in configuring pin%d for clkout", GPIO_PIN_55);
++ status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->tx_dmach),
++ spi_dma_callback_handler, 0, 0,
++ (void *)drv_data);
++ if (status) {
++ nmdk_error("Error requesting callback dmach intr handler %d", status);
++ goto err_tx_clbk_request;
++ }
++ } else {
++ chip->enable_dma = 0;
++ nmdk_dbg(":::: DMA mode NOT set in controller state\n");
++ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_RDMAE, 0);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_TDMAE, 1);
+ }
-+
-+ /* disable NOR flash write protection */
-+ /* CHECK if this clashes with NOR and NAND settings of FSMC */
-+ *((volatile unsigned short *)(NOMADIK_CPLD_RGPO1_VA)) |=
-+ ETH_DAUGHTER_CARD_RESET;
+
-+ set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING);
-+}
+
-+static struct resource smc91x_resources[] = {
-+ [0] = {
++ /**** GCR Reg Config *****/
+
-+ .name = "smc91x-regs",
-+ .start = (NOMADIK_ETH0_BASE + 0x300),
-+ .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .start = IRQNO_GPIO(SMC91111_IRQ),
-+ .end = IRQNO_GPIO(SMC91111_IRQ),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RECEIVER_DISABLED, MSP_GCR_MASK_RXEN,0);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RX_FIFO_ENABLED, MSP_GCR_MASK_RFFEN,1);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMITTER_DISABLED, MSP_GCR_MASK_TXEN,8);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FIFO_ENABLED, MSP_GCR_MASK_TFFEN,9);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_POL_LOW, MSP_GCR_MASK_TFSPOL,10);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_INT, MSP_GCR_MASK_TFSSEL,11);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMIT_DATA_WITH_DELAY, MSP_GCR_MASK_TXDDL,15);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SAMPLE_RATE_GEN_ENABLE, MSP_GCR_MASK_SGEN,16);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_CLOCK_INTERNAL, MSP_GCR_MASK_SCKSEL,18);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_FRAME_GEN_ENABLE, MSP_GCR_MASK_FGEN,20);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, SPI_BURST_MODE_DISABLE, MSP_GCR_MASK_SPIBME,23);
+
-+static struct platform_device smc91x_device = {
-+ .name = "smc91x",
-+ .id = 0,
-+ .num_resources = ARRAY_SIZE(smc91x_resources),
-+ .resource = smc91x_resources,
-+};
+
-+/*
-+ * touchpanel
-+ */
-+#ifndef TOUCHP_DEBUG
-+#define TOUCHP_DEBUG 0 /* default debug messages are disabled */
-+#endif /* */
++ if(chip_info->lbm == LOOPBACK_ENABLED)
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_ENABLED, MSP_GCR_MASK_LBM, 7);
++ else
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_DISABLED, MSP_GCR_MASK_LBM, 7);
+
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */
-+#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
+
-+/**
-+ * nomadik_tp_ssp_board_init - board specific ssp data path setup
-+ *
-+ * This routine initializes the SSP for touchpanel operation
-+ * SSP is interfaced with ADS7843 through CPLD hence respective
-+ * interface need to be enabled for NDK10
-+ * make bit COB_CTL(MSP2_SSP_SWAP) low to connect STn8810 SSP to EXP SSP
-+ * make bit COB_CTL(SSP_EN) high to enable SSP on STn8810 side
-+ */
-+int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
-+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_cob_ctl((nomadik_epio_read_cob_ctl() &
-+ (~MSP2_SSP_SWAP)) | SSP_EN);
-+ return (0);
-+}
++ if(chip_info->hierarchy == SPI_MASTER)
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_MASTER, MSP_GCR_MASK_TCKSEL, 14);
++ else
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_SLAVE, MSP_GCR_MASK_TCKSEL, 14);
+
-+/**
-+ * nomadik_tp_gpio_board_init - board specific gpio initialization
-+ * @mode: mode of operation (polling[0] or interrupt[<0]
-+ *
-+ * This routine initializes the GPIO for touchpanel operation
-+ * RETURN: GPIO nmdk_error code
-+ */
-+gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
-+{
-+ gpio_error status = GPIO_OK;
-+ nmdk_dbg_ftrace();
+
-+ /* Set PENIRQ pin configuration */
-+ set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING);
-+ /* Enable GPIOs through CPLD for access/interrupts on ndk10 */
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | GPIO_EN);
++ if(chip_info->proto_params.moto.clk_phase == SPI_CLK_ZERO_CYCLE_DELAY)
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_ZERO_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
++ else
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_HALF_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
+
-+ return status;
-+}
++ if(chip_info->proto_params.moto.clk_pol == SPI_CLK_POL_IDLE_HIGH)
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_HIGH, MSP_GCR_MASK_TCKPOL,13);
++ else
++ SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_LOW, MSP_GCR_MASK_TCKPOL,13);
+
-+/**
-+ * nomadik_tp_pen_down - returns pen touch status
-+ */
-+t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
-+{
-+ gpio_data pen_down;
+
-+ nmdk_dbg_ftrace();
-+ nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
-+ nmdk_dbg2("%s(): pen_down = 0x%d", __FUNCTION__, pen_down);
-+ return ((t_bool) pen_down);
-+}
++ /**** RCF Reg Config *****/
++ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_IGNORE_RX_FRAME_SYNC_PULSE, MSP_RCF_MASK_RFSIG, 15);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_1BIT_DATA_DELAY, MSP_RCF_MASK_RDDLY, 13);
++ if(chip_info->endian_rx == SPI_FIFO_LSB)
++ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_LSB , MSP_RCF_MASK_RENDN, 12);
++ else
++ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_MSB , MSP_RCF_MASK_RENDN, 12);
+
-+/**
-+ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
-+{
-+ nmdk_dbg_ftrace();
-+// enable_irq(p_adsContext->irq);
-+}
++ SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, chip_info->controller.msp.data_size , MSP_RCF_MASK_RP1ELEN, 0);
+
-+/**
-+ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
-+{
-+ nmdk_dbg_ftrace();
-+// disable_irq(p_adsContext->irq);
-+}
++ /**** TCF Reg Config *****/
++ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_IGNORE_TX_FRAME_SYNC_PULSE, MSP_TCF_MASK_TFSIG, 15);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_1BIT_DATA_DELAY, MSP_TCF_MASK_TDDLY, 13);
++ if(chip_info->endian_rx == SPI_FIFO_LSB)
++ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_LSB , MSP_TCF_MASK_TENDN, 12);
++ else
++ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_MSB , MSP_TCF_MASK_TENDN, 12);
++ SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, chip_info->controller.msp.data_size , MSP_TCF_MASK_TP1ELEN, 0);
+
-+/**
-+ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
-+ *
-+ * set TOUCHP_SSP_CS pin high to disable SSP chip select for ads7843
-+ */
-+void nomadik_tp_spi_cs_disable(void)
-+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() |
-+ TOUCHP_SSP_CS);
-+}
++ /**** SRG Reg Config *****/
++ SPI_REG_WRITE_BITS(chip->regs.mspr.srg, sckdiv , MSP_SRG_MASK_SCKDIV , 0);
+
-+/**
-+ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
-+ *
-+ * set TOUCHP_SSP_CS pin low to enable SSP chip select for ads7843
-+ */
-+void nomadik_tp_spi_cs_enable(void)
-+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
-+ (~TOUCHP_SSP_CS));
-+}
++ /* Save controller_state */
++ spi_set_ctldata(spi, chip);
++ return status;
+
-+static struct touchp_device touchp_board = {
-+ .ssp_init = nomadik_tp_ssp_board_init,
-+ .gpio_init = nomadik_tp_gpio_board_init,
-+ .pdown = nomadik_tp_pen_down,
-+ .pirq_en = nomadik_tp_pen_down_irq_enable,
-+ .pirq_dis = nomadik_tp_pen_down_irq_disable,
-+ .cs_en = nomadik_tp_spi_cs_disable,
-+ .cs_dis = nomadik_tp_spi_cs_enable,
-+ .samples = 100, /*samples per second*/
-+ .pollsamples = 10, /*polling per second*/
-+};
++err_tx_clbk_request:
++ if (chip->dma_info->tx_dmach != -1) {
++ free_dma(chip->dma_info->tx_dmach);
++ }
++err_tx_dmach_request:
++err_rx_clbk_request:
++ if (chip->dma_info->rx_dmach != -1) {
++ free_dma(chip->dma_info->rx_dmach);
++ }
++err_rx_dmach_request:
++ chip->dma_info->tx_dmach = -1;
++ chip->dma_info->rx_dmach = -1;
++err_config_params:
++err_first_setup:
++ if(chip->dma_info)
++ kfree(chip->dma_info);
++ kfree(chip);
++err_request_irq:
++ free_irq(drv_data->adev->irq[0], drv_data);
++err_altfunc_enable:
++ nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
++err_out:
++ switch(master->bus_num) {
++ case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user == MSP_USER_SPI) {
++ down(&drv_data->flag_msp0->lock);
++ drv_data->flag_msp0->user = MSP_NO_USER;
++ up(&drv_data->flag_msp0->lock);
++ nmdk_dbg("Flag cleanup for MSP0\n");
++ }
++ else {
++ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp0->user);
++ status = -EFAULT;
++ }
++ break;
++ case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user == MSP_USER_SPI) {
++ down(&drv_data->flag_msp1->lock);
++ drv_data->flag_msp1->user = MSP_NO_USER;
++ up(&drv_data->flag_msp1->lock);
++ nmdk_dbg("Flag cleanup for MSP1\n");
++ }
++ else {
++ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
++ status = -EFAULT;
++ }
++ break;
++ case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user == MSP_USER_SPI) {
++ down(&drv_data->flag_msp2->lock);
++ drv_data->flag_msp2->user = MSP_NO_USER;
++ up(&drv_data->flag_msp2->lock);
++ nmdk_dbg("Flag cleanup for MSP2\n");
++ }
++ else {
++ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
++ status = -EFAULT;
++ }
++ break;
++ }
+
-+static struct resource touchp_resources[] = {
-+ [0] = {
-+ .start = IRQNO_GPIO(TOUCHP_IRQ),
-+ .end = IRQNO_GPIO(TOUCHP_IRQ),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
++ return status;
++}
+
-+static struct platform_device touchp_device = {
-+ .name = "nmdk-tp",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &touchp_board,
-+ },
-+ .num_resources = ARRAY_SIZE(touchp_resources),
-+ .resource = touchp_resources,
-+};
++#endif
+
-+/*
-+ ***********************************************************************
-+ */
-+#define KEYPAD_NAME "KEYPAD"
+
-+#ifndef KEYPAD_DEBUG
-+#define KEYPAD_DEBUG 0
++int msp_probe(struct amba_device *adev, void *data)
++{
++ int status = 0;
++ struct device *dev;
++ struct nmdk_spi_master_cntlr *platform_info;
++
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++ struct spi_master *master;
++ struct driver_data *drv_data = NULL; /*Data for this driver */
++ struct resource *res;
++ int irq;
+#endif
++ dev = &adev->dev;
++ platform_info = (struct nmdk_spi_master_cntlr *)(dev->platform_data);
++ if (platform_info == NULL) {
++ dev_err(&adev->dev, "probe - no platform data supplied\n");
++ status = -ENODEV;
++ goto err_no_pdata;
++ }
+
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++ if(platform_info->id == MSP_0_CONTROLLER) {
++ flag_msp0= kmalloc(sizeof(msp_flag), GFP_KERNEL);
++ if(!flag_msp0) {
++ status = -ENOMEM;
++ printk(KERN_ERR "No mem available for MSP0 flag\n");
++ goto err_msp0;
++ }
++ flag_msp0->user = MSP_NO_USER;
++ init_MUTEX(&flag_msp0->lock);
++ init_waitqueue_head(&wait[0]);
++ nmdk_dbg("In msp_probe flag_msp0 is %d\n", flag_msp0->user);
++ }
++ if(platform_info->id == MSP_1_CONTROLLER) {
++ flag_msp1= kmalloc(sizeof(msp_flag), GFP_KERNEL);
++ if(!flag_msp1) {
++ status = -ENOMEM;
++ printk(KERN_ERR "No mem available for MSP1 flag\n");
++ goto err_msp1;
++ }
++ flag_msp1->user = MSP_NO_USER;
++ init_MUTEX(&flag_msp1->lock);
++ init_waitqueue_head(&wait[1]);
++ nmdk_dbg("In msp_probe flag_msp1 is %d\n", flag_msp1->user);
++ }
++ if(platform_info->id == MSP_2_CONTROLLER) {
++ flag_msp2= kmalloc(sizeof(msp_flag), GFP_KERNEL);
++ if(!flag_msp2) {
++ status = -ENOMEM;
++ printk(KERN_ERR "No mem available for MSP2 flag\n");
++ goto err_msp2;
++ }
++ flag_msp2->user = MSP_NO_USER;
++ init_MUTEX(&flag_msp2->lock);
++ init_waitqueue_head(&wait[2]);
++ nmdk_dbg("In msp_probe flag_msp2 is %d\n", flag_msp2->user);
++ }
++ nmdk_dbg_ftrace();
+
-+/*key scan constants*/
-+#define KSCAN_ALLROWS 0x001F
-+#define KSCAN_ALLCOLS 0x07E0
-+#define KSCAN_ROW0 0x0001
-+#define KSCAN_ROW1 0x0002
-+#define KSCAN_ROW2 0x0004
-+#define KSCAN_ROW3 0x0008
-+#define KSCAN_ROW4 0x0010
-+#define KSCAN_COL0 0x0020
-+#define KSCAN_COL1 0x0040
-+#define KSCAN_COL2 0x0080
-+#define KSCAN_COL3 0x0100
-+#define KSCAN_COL4 0x0200
-+#define KSCAN_AUX 0x0400 /* this line needs to set to get keypad intr */
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++ /* Allocate master with space for drv_data */
++ master = spi_alloc_master(dev, sizeof(struct driver_data));
++ if (master == NULL) {
++ dev_err(&adev->dev, "probe - cannot alloc spi_master\n");
++ status = -ENOMEM;
++ goto err_no_mem;
++ }
+
-+unsigned short const keychkval_set[] = {
-+ (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS
-+};
++ drv_data = spi_master_get_devdata(master);
++ drv_data->master = master;
++ drv_data->master_info = platform_info;
++ drv_data->adev = adev;
+
-+unsigned short const keychkval_read[] = {
-+ KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4
-+};
++ drv_data->dma_ongoing = 0;
+
-+/**
-+ * nomadik_kp_ghostkey_detect - ghost key detect function
-+ * @rowval: row in which ghost key to be detected
-+ *
-+ * when more than one key is pressed in the same row the keypad logic cannot
-+ * detect proper key press, the logic here detects multiple keypress on a
-+ * single row and returns error
-+ */
-+int nomadik_kp_ghostkey_detect(short rowval)
-+{
-+ int row;
-+ int ghcnt = 0;
++ /*Fetch the Resources, using platform data */
+
-+ for (row = 0; row < MAX_KPROW; row++) {
-+ if (0 == (rowval & keychkval_read[row])) {
-+ /*keypr detected */
-+ ghcnt++;
-+ }
-+ /* return error if more than one keys are pressed in a row */
-+ if (1 < ghcnt)
-+ return (-1);
++ res = &(adev->res);
++ if (res == NULL) {
++ dev_err(&adev->dev, "probe - MEM resources not defined\n");
++ status = -ENODEV;
++ goto err_no_iores;
++ }
++ /*Get Hold of Device Register Area... */
++ drv_data->regs = ioremap(res->start, (res->end - res->start));
++ if (drv_data->regs == NULL) {
++ status = -ENODEV;
++ goto err_no_iores;
++ }
++ irq = adev->irq[0];
++ if (irq <= 0) {
++ status = -ENODEV;
++ goto err_no_iores;
+ }
-+ return (0);
-+}
-+
-+/**
-+ * nomadik_kp_key_scan - keypad scan and report event function
-+ *
-+ * Scans through keypad hardware and updates the key status for key press
-+ * or key release event to upper layer
-+ */
-+int nomadik_kp_key_scan(struct keypad_t *kp)
-+{
-+ short val;
-+ u8 row, col;
-+ int keyp_cnt = 0;
-+ u8 *p_kcode;;
+
-+ nmdk_dbg_ftrace();
-+ for (col = 0; col < MAX_KPCOL; col++) {
-+ p_kcode = kp->board->kcode_tbl + col;
-+ nomadik_epio_write_keypad(keychkval_set[col]);
-+ val = nomadik_epio_read_keypad();
-+ val &= KSCAN_ALLROWS;
-+ if (0 == nomadik_kp_ghostkey_detect(val)) {
-+ for (row = 0; row < MAX_KPROW; row++) {
-+ if (0 == (val & keychkval_read[row])) {
-+ /*keypr detected */
-+ keyp_cnt++;
-+ if (kp->key_state[row][col] ==
-+ KEYPAD_STATE_DEFAULT) {
-+ input_report_key(kp->inp_dev,
-+ *p_kcode, 1);
-+ nmdk_dbg("P:%d ", *p_kcode);
-+ kp->key_state[row][col] =
-+ KEYPAD_STATE_PRESSACK;
-+ }
-+ } else {
-+ /*key not pressed detected */
-+ if (kp->key_state[row][col] ==
-+ KEYPAD_STATE_PRESSACK) {
-+ input_report_key(kp->inp_dev,
-+ *p_kcode, 0);
-+ nmdk_dbg("R:%d ", *p_kcode);
-+ kp->key_state[row][col] =
-+ KEYPAD_STATE_DEFAULT;
-+ }
-+ }
-+ p_kcode += MAX_KPROW;
-+ }
-+ } else
-+ keyp_cnt += 0x100; /* to flag ghost keypress detection */
++ /*Set flag for MSPx*/
++ switch(platform_info->id) {
++ case MSP_0_CONTROLLER:
++ drv_data->flag_msp0 = (spi_msp_user *)flag_msp0;
++ break;
++ case MSP_1_CONTROLLER:
++ drv_data->flag_msp1 = (spi_msp_user *)flag_msp1;
++ break;
++ case MSP_2_CONTROLLER:
++ drv_data->flag_msp2 = (spi_msp_user *)flag_msp2;
++ break;
++ default:
++ dev_err(&adev->dev, "unknown controller Id %d\n", platform_info->id);
++ status = -EINVAL;
++ break;
+ }
-+ /* pull down all rows to detect any keypress */
-+ nomadik_epio_write_keypad(KSCAN_ALLROWS);
-+ return (keyp_cnt);
-+}
+
-+/**
-+ * nomadik_kp_init_key_hardware - keypad hardware initialization
-+ *
-+ * Initializes the keypad hardware specific parameters.
-+ * This function will be called by nomadik_keypad_init function during init
-+ * Initialize keypad interrupt handler for interrupt mode operation if enabled
-+ * Initialize Keyscan matrix
-+ ****************************************************************************
-+ */
-+int nomadik_kp_init_key_hardware(struct keypad_t *kp)
-+{
-+ int err;
-+ gpio_data pin;
++ if(status == -EINVAL)
++ goto err_no_irqres;
+
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_keypad(KSCAN_ALLROWS | KSCAN_ALLCOLS);
-+ nomadik_epio_read_keypad();
-+ if ((KSCAN_ALLROWS | KSCAN_ALLCOLS) != nomadik_epio_read_keypad()) {
-+ /*check wrong key */
-+ nmdk_error("H/w error....");
-+ goto kphwiniterr_hwer;
++ nmdk_dbg(":::: MSP Controller = %d\n", platform_info->id);
++ drv_data->execute_cmd = msp_controller_cmd;
++ drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
++ master->setup = nomadik_msp_setup;
++
++ /*Required Info for an SPI controller */
++ /*Bus Number Which has been Assigned to this SPI controller on this board */
++ master->bus_num = (u16) platform_info->id;
++ master->num_chipselect = platform_info->num_chipselect;
++ master->cleanup = nomadik_spi_cleanup;
++ master->transfer = nomadik_spi_transfer;
++
++ nmdk_dbg(":::: BUSNO: %d\n", master->bus_num);
++ /* Initialize and start queue */
++ status = init_queue(drv_data);
++ if (status != 0) {
++ dev_err(&adev->dev, "probe - problem initializing queue\n");
++ goto err_init_queue;
+ }
-+ if (!kp->mode) { /* true if interrupt mode operation */
-+ /* Enable keypad interrupt generation logic in CPLD on ndk10 */
-+ nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS);
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() |
-+ GPIO_EN);
-+ nmdk_dbg("keypad interrupt CPLD logic enabled");
++ status = start_queue(drv_data);
++ if (status != 0) {
++ dev_err(&adev->dev, "probe - problem starting queue\n");
++ goto err_start_queue;
++ }
++ /*Initialize tasklet for DMA transfer*/
++ tasklet_init(&drv_data->spi_dma_tasklet, nomadik_spi_tasklet,
++ (unsigned long)drv_data);
+
-+ if (!kp->irq) {
-+ nmdk_error("keypad_irq cannot get in kpinit");
-+ err = -1;
-+ goto kphwiniterr_pinconfig;
-+ }
-+ set_irq_type(kp->irq, SA_TRIGGER_FALLING);
-+ nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(kp->irq), &pin);
-+ if (!pin) {
-+ /*check wrong configuration */
-+ nmdk_error("H/w error...(check sw8 on board)");
-+ goto kphwiniterr_itpin;
-+ }
++ /* Register with the SPI framework */
++ platform_set_drvdata(adev, drv_data);
++ status = spi_register_master(master);
++ if (status != 0) {
++ dev_err(&adev->dev, "probe - problem registering spi master\n");
++ goto err_spi_register;
+ }
++ dev_dbg(dev, "probe succeded\n");
++ nmdk_dbg(" Bus Number = %d, IRQ Line = %d, Virtual Addr: %x\n", master->bus_num, irq, (u32)(drv_data->regs) );
+ return 0;
++#endif
++ return status;
+
-+ kphwiniterr_itpin:
-+ kphwiniterr_pinconfig:
-+ kphwiniterr_hwer:
-+ return -1;
-+}
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++ err_init_queue:
++ err_start_queue:
++ err_spi_register:
++ destroy_queue(drv_data);
++ err_no_irqres:
++ err_no_iores:
++ spi_master_put(master);
++ err_no_mem:
++#endif
++ if((flag_msp2) && (platform_info->id == MSP_2_CONTROLLER))
++ kfree(flag_msp2);
++ err_msp2:
++ if((flag_msp1) && (platform_info->id == MSP_1_CONTROLLER))
++ kfree(flag_msp1);
++ err_msp1:
++ if((flag_msp0) && (platform_info->id == MSP_0_CONTROLLER))
++ kfree(flag_msp0);
++ err_msp0:
++ err_no_pdata:
++ return status;
+
-+/**
-+ * nomadik_kp_exit_key_hardware- keypad hardware exit function
-+ *
-+ * This function will be called by nomadik_keypad_exit function during module
-+ * exit, frees keypad interrupt if enabled
-+ */
-+int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
-+{
-+ nmdk_dbg_ftrace();
-+ return 0;
+}
+
-+/**
-+ * nomadik_kp_key_irqen- enables keypad interrupt
-+ *
-+ * enables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqen(struct keypad_t *kp)
++static int msp_remove(struct amba_device *adev)
+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS);
-+ return 0;
-+}
++ struct driver_data *drv_data = platform_get_drvdata(adev);
++ struct device *dev = &adev->dev;
++ struct nmdk_spi_master_cntlr *platform_info;
++ int irq;
++ int status = 0;
++ if (!drv_data)
++ return 0;
+
-+/**
-+ * nomadik_kp_key_irqdis- disables keypad interrupt
-+ *
-+ * disables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqdis(struct keypad_t *kp)
-+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_keypad(KSCAN_ALLROWS);
-+ return 0;
-+}
++ platform_info = dev->platform_data;
+
-+/*
-+ * Initializes the key scan table (lookup table) as per pre-defined the scan
-+ * codes to be passed to upper layer with respective key codes
-+ */
-+static u8 kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
-+ {KEY_DOWN, KEY_END, KEY_KPASTERISK, KEY_0, KEY_COMMA},
-+ {KEY_RIGHT, KEY_F5, KEY_7, KEY_8, KEY_9},
-+ {KEY_ENTER, KEY_LEFT, KEY_4, KEY_5, KEY_6},
-+ {KEY_RIGHTMETA, KEY_F4, KEY_1, KEY_2, KEY_3},
-+ {KEY_LEFTMETA, KEY_UP, KEY_F1, KEY_F2, KEY_F3}
-+};
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++ /* Remove the queue */
++ status = destroy_queue(drv_data);
++ if (status != 0) {
++ dev_err(&adev->dev, "queue remove failed (%d)\n", status);
++ return status;
++ }
++ drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
+
-+static struct keypad_device keypad_board = {
-+ .init = nomadik_kp_init_key_hardware,
-+ .exit = nomadik_kp_exit_key_hardware,
-+ .scan = nomadik_kp_key_scan,
-+ .irqen = nomadik_kp_key_irqen,
-+ .irqdis = nomadik_kp_key_irqdis,
-+ .kcode_tbl = (u8 *) kpd_lookup_tbl,
-+ .krow = 8,
-+ .kcol = 8,
-+};
++ irq = adev->irq[0];
++ if (irq >= 0)
++ free_irq(irq, drv_data);
+
-+static struct resource keypad_resources[] = {
-+ [0] = {
-+ .start = IRQNO_GPIO(KEYPAD_IRQ),
-+ .end = IRQNO_GPIO(KEYPAD_IRQ),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
++ /* Release map resources */
++ iounmap(drv_data->regs);
++ tasklet_disable(&drv_data->pump_transfers);
++ tasklet_kill(&drv_data->spi_dma_tasklet);
++ nomadik_gpio_altfuncdisable(platform_info->gpio_alt_func, platform_info->device_name);
+
-+static struct platform_device keypad_device = {
-+ .name = "nmdk-kp",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &keypad_board,
-+ },
-+ .num_resources = ARRAY_SIZE(keypad_resources),
-+ .resource = keypad_resources,
-+};
++ /* Disconnect from the SPI framework */
++ spi_unregister_master(drv_data->master);
++ spi_master_put(drv_data->master);
+
-+/*
-+ ***********************************************************************
-+ */
-+static struct platform_device *nmdk_platform_devices[] __initdata = {
-+ &smc91x_device,
-+ &keypad_device,
-+ &touchp_device,
-+#ifdef CONFIG_MTD
-+ &nomadik_nand_flash,
-+ &nomadik_nor_flash,
++ /* Prevent double remove */
++ platform_set_drvdata(adev, NULL);
++ dev_dbg(&adev->dev, "remove succeded\n");
+#endif
-+};
++ if(platform_info->id == MSP_0_CONTROLLER) {
++ if(flag_msp0)
++ kfree(flag_msp0);
++ else
++ printk("MSP Error:why flag_msp0==NULL???");
++ }
++ if(platform_info->id == MSP_1_CONTROLLER) {
++ if(flag_msp1)
++ kfree(flag_msp1);
++ else
++ printk("MSP Error:why flag_msp1==NULL???");
++ }
++ if(platform_info->id == MSP_2_CONTROLLER) {
++ if(flag_msp2)
++ kfree(flag_msp2);
++ else
++ printk("MSP Error:why flag_msp2==NULL???");
++ }
+
-+void add_nmdk_platform_devices(void)
-+{
-+ platform_add_devices(nmdk_platform_devices,
-+ ARRAY_SIZE(nmdk_platform_devices));
-+ nomadik_epio_init();
-+ nomadik_platform_board_init();
-+ nomadik_fsmc_init();
-+ nomadik_pepperpot_board_init();
-+ nomadik_smc91x_irq_init();
++ return 0;
+}
+
++static struct amba_id msp_ids[] = {
++ {
++ .id = MSP_PER_ID,
++ .mask = MSP_PER_MASK,
++ },
++ {0, 0},
++};
+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1023 @@
-+/*
-+ * linux/arch/arm/mach-nomadik/ndk15c02_devices.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2, as
-+ * published by the Free Software Foundation.
-+ *
-+ * NDK15C02 board specifc driver defination
-+ */
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/amba/bus.h>
-+#include <linux/spi/spi.h>
-+#include <linux/amba/kmi.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/setup.h>
-+#include <asm/param.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/time.h>
-+#include <asm/arch/i2c.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/kpd.h>
-+#include <asm/arch/touchp.h>
-+#include <asm/arch/fsmc.h>
-+#ifdef CONFIG_MTD
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/concat.h>
-+#include <asm/arch/nandflash.h>
-+#include <asm/mach/flash.h>
-+#endif
-+#include <asm/arch/debug.h>
-+
-+#define BOARD_NAME CONFIG_NOMADIK_PLATFORM
-+#ifndef BOARD_DEBUG
-+#define BOARD_DEBUG 0
-+#endif
++static struct amba_driver msp_driver = {
++ .drv = {
++ .name = "MSP",
++ },
++ .id_table = msp_ids,
++ .probe = msp_probe,
++ .remove = msp_remove
++};
+
-+#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++EXPORT_SYMBOL(nomadik_msp_configure);
++EXPORT_SYMBOL(nomadik_msp_send_data);
++EXPORT_SYMBOL(nomadik_msp_receive_data);
++EXPORT_SYMBOL(nomadik_msp_transceive_data);
++EXPORT_SYMBOL(nomadik_msp_enable);
++EXPORT_SYMBOL(nomadik_msp_disable);
++EXPORT_SYMBOL(nomadik_msp_flush_input);
+
-+/**
-+ * nomadik_clcd_board_enable - enables board specific clcd prameters
-+ *
-+ * Settings to enable backlight and pannel voltage regulator for NDK15
-+ */
-+void nomadik_clcd_enable(void *fbp)
++static int __init nomadik_msp_mod_init(void)
+{
-+ /* not implimented for this board */
++ return amba_driver_register(&msp_driver);
+}
+
-+/**
-+ * nomadik_clcd_board_disable - disables board specific clcd prameters
-+ *
-+ * Settings to disable backlight and pannel voltage regulator for NDK10
-+ */
-+void nomadik_clcd_disable(void *fbp)
++static void __exit nomadik_msp_exit(void)
+{
-+ /* not implimented for this board */
++ amba_driver_unregister(&msp_driver);
++ return;
+}
++module_init(nomadik_msp_mod_init);
++module_exit(nomadik_msp_exit);
+
-+//#ifdef CONFIG_MMC_NOMADIK
-+/*
-+ * Settings to configure MMC controller for NDK10
++MODULE_AUTHOR("STMicroelectronics Pvt Ltd");
++MODULE_DESCRIPTION("NOMADIK MSP driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/msp.h
+@@ -0,0 +1,383 @@
++/*linux/drivers/char/nomadik-msp.h
++ *
++ * Driver for Nomadik STN8810 MSP device. Note that this module MUST NOT
++ * attempt to load before the i2c and gpio drivers are loaded.
++ *
++ * Copyright 2006 STMicroelectronics Pvt. Ltd.
++ *
++ * This program is free sofstware; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
+ */
-+int nomadik_mmc_configure(struct amba_device *dev)
-+{
-+ int ret;
-+ gpio_config mmc_pin;
-+ char x = val_volt;
-+
-+ mmc_pin.dev_name = dev->dev.bus_id;
-+ mmc_pin.mode = GPIO_MODE_SOFTWARE;
-+ mmc_pin.direction = GPIO_DIR_OUTPUT;
-+ mmc_pin.trig = GPIO_TRIG_DISABLE;
-+ mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
+
-+ ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
-+ if (ret) {
-+ nmdk_error("Error in setting GPIO_PIN_75");
-+ goto mmcconf_exit;
-+ }
-+ /* this enables power path from toureg to mmc */
-+ ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id);
-+ if (ret) {
-+ nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
-+ goto deallocate_pin_75;
-+ }
++#ifndef NMDK_MSP_HEADER
++#define NMDK_MSP_HEADER
+
-+ ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
-+ if (ret) {
-+ nmdk_error("Error in writing value to touareg register");
-+ goto deallocate_pin_75;
-+ }
++struct msp_register
++{
++ u32 fifo;
++ u32 global_ctrl;
++ u32 tx_config;
++ u32 rx_config;
++ u32 srg_ctrl;
++ u32 status;
++ u32 dma_ctrl;
++ u32 reserved0;
++ u32 irq_mask;
++ u32 raw_irq_status;
++ u32 masked_irq_status;
++ u32 irq_clear;
++ u32 multichannel_ctrl;
++ u32 rx_compare_val;
++ u32 rx_compare_mask;
++ u32 reserved1;
++ u32 tx_enable_ch0;
++ u32 tx_enable_ch1;
++ u32 tx_enable_ch2;
++ u32 tx_enable_ch3;
++ u32 reserved2[4];
++ u32 rx_enable_ch0;
++ u32 rx_enable_ch1;
++ u32 rx_enable_ch2;
++ u32 rx_enable_ch3;
++ u32 reserved3[4];
++ u32 test_ctrl;
++ u32 integration_test_input;
++ u32 integration_test_output;
++ u32 test_data;
++};
+
-+ ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
-+ if (ret) {
-+ nmdk_error("Error in gpio Altfunction enable");
-+ goto deallocate_pin_75;
-+ }
-+ return ret;
++struct msp_context {
++ u8 direction;
++ u8 mode;
++ u8 protocol;
++ int frame_freq;
++ int frame_size;
++ enum msp_data_size requested_data_size;
++ enum msp_data_size actual_data_size;
+
-+ deallocate_pin_75:
-+ nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
-+ mmcconf_exit:
-+ return ret;
++ u32 rx_channel_0_enable;
++ u32 rx_channel_1_enable;
++ u32 rx_channel_2_enable;
++ u32 rx_channel_3_enable;
++ u32 tx_channel_0_enable;
++ u32 tx_channel_1_enable;
++ u32 tx_channel_2_enable;
++ u32 tx_channel_3_enable;
++ u32 multichannel_ctrl_reg;
++ u32 rx_compare_mask_reg;
++ u32 irq_mask_reg;
+
-+}
++ u8 compression_mode;
++ u8 expansion_mode;
++ u8 coprocessor_mode;
++ int msp_disable;
++};
+
-+void nomadik_mmc_restore_default(struct amba_device *dev)
++ struct msp_mode_status
+{
-+ nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
-+ nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
-+}
-+//#endif
++ int work_mode;
++ int phase_mode;
++ int stereo_mode;
++ volatile u16 *it_mono_data_flow;
++ volatile u32 *it_stereo_data_flow;
++ volatile u32 it_halfwords_count;
++ volatile u32 flow_error_count;
++} msp_mode_status;
+
-+static int fsmc_platform_init(void)
++
++/* Single or dual phase mode */
++enum
+{
-+ unsigned char __iomem *fsmc_base;
++ MSP_SINGLE_PHASE,
++ MSP_DUAL_PHASE
++};
+
-+ nmdk_dbg_ftrace();
-+ /*Following Settings done for NAND flash protect off */
-+ fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
+
-+ /* for NOR accesss */
-+ /* Initialize the fsmc bank 0 */
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
-+ /* Initialize the fsmc bank 1 used for ethernet controller */
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db;
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702; /*old 00000702 */
++/* Transmit/Receive shifter status
++-----------------------------------*/
++enum
++{
++ MSP_SxHIFTER_IDLE = 0,
++ MSP_SHIFTER_WORKING = 1
++};
+
-+ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
-+ /* Above Settings done for NAND flash protect off */
-+ return 0;
-+}
+
-+static struct resource fsmc_resources[] = {
-+ [0] = {
-+ .start = NOMADIK_FSMC_BASE,
-+ .end = NOMADIK_FSMC_BASE + SZ_4K - 1,
-+ .flags = IORESOURCE_MEM,
-+ },
++/* Transmit/Receive FIFO status
++---------------------------------*/
++enum
++{
++ MSP_FIFO_FULL,
++ MSP_FIFO_PART_FILLED,
++ MSP_FIFO_EMPTY
+};
+
-+struct fsmc_platform_data fsmc_data = {
-+ .init = fsmc_platform_init,
-+};
+
-+static struct platform_device fsmc_device = {
-+ .name = "NOMADIK-FSMC",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &fsmc_data,
-+ },
-+ .num_resources = ARRAY_SIZE(fsmc_resources),
-+ .resource = fsmc_resources,
++/* Frame length
++------------------*/
++enum
++{
++ MSP_FRAME_LENGTH_1 = 0,
++ MSP_FRAME_LENGTH_2 = 1,
++ MSP_FRAME_LENGTH_4 = 3,
++ MSP_FRAME_LENGTH_8 = 7,
++ MSP_FRAME_LENGTH_12 = 11,
++ MSP_FRAME_LENGTH_16 = 15,
++ MSP_FRAME_LENGTH_20 = 19,
++ MSP_FRAME_LENGTH_32 = 31,
++ MSP_FRAME_LENGTH_48 = 47,
++ MSP_FRAME_LENGTH_64 = 63
+};
+
-+#ifdef CONFIG_MTD
-+static struct resource nandflash_resources[] = {
-+ [0] = {
-+ .name = "cmem_address",
-+ .start = NAND_B0_CMEM_ADDR,
-+ .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .name = "cmem_command",
-+ .start = NAND_B0_CMEM_CMD,
-+ .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [2] = {
-+ .name = "cmem_data",
-+ .start = NAND_B0_CMEM_DATA,
-+ .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
++/* Element length */
++enum
++{
++ MSP_ELEM_LENGTH_8 = 0,
++ MSP_ELEM_LENGTH_10 = 1,
++ MSP_ELEM_LENGTH_12 = 2,
++ MSP_ELEM_LENGTH_14 = 3,
++ MSP_ELEM_LENGTH_16 = 4,
++ MSP_ELEM_LENGTH_20 = 5,
++ MSP_ELEM_LENGTH_24 = 6,
++ MSP_ELEM_LENGTH_32 = 7
+};
+
-+#define NAND_STM_LP_OPTIONS \
-+ (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
-+
-+int nomadik_nandflash_exit(void)
-+{
-+ return 0;
+
-+}
-+int nomadik_nandflash_init(void)
++/* Data delay (in bit clock cycles)
++---------------------------------------*/
++enum
+{
-+ /*
-+ * FSMC initialization
-+ * 0x0000001e => PCR0
-+ * 0x000d0a00 => PMEM0
-+ * 0x00100a00 => PATT0
-+ */
-+
-+/* pcr0.address_low = 0;*/
-+ gpio_config nmdknand_pin_config;
-+ nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
-+ nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
-+ nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
-+ nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+ nmdknand_pin_config.dev_name = "nand";
-+ /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */
-+ nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config);
-+ nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name);
-+ /*Following Settings done for NAND flash protect off */
-+ nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config);
-+ nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name);
-+ nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name);
++ MSP_DELAY_0 = 0,
++ MSP_DELAY_1 = 1,
++ MSP_DELAY_2 = 2,
++ MSP_DELAY_3 = 3
++};
+
-+ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
-+ DEFAULT_PCR0_VALUE;
-+ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
-+ DEFAULT_PMEM0_VALUE;
-+ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
-+ DEFAULT_PATT0_VALUE;
-+ return 0;
-+}
+
-+const unsigned char lookup_t[256] = {
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
++/* Configurations of clocks (transmit, receive or sample rate generator)
++-------------------------------------------------------------------------*/
++enum
++{
++ MSP_RISING_EDGE = 0,
++ MSP_FALLING_EDGE = 1
+};
+
-+int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
-+ u_char * ecc)
++/* Protocol dependant parameters list */
++struct msp_protocol_desc
+{
-+ unsigned int sumCol = 0;
-+ unsigned int datum, temp;
-+ unsigned int glob_parity;
-+ const int ecc_n_bytes = 512;
-+ int i;
++ u32 phase_mode;
++ u32 frame_len_1;
++ u32 frame_len_2;
++ u32 element_len_1;
++ u32 element_len_2;
++ u32 data_delay;
++ u32 tx_clock_edge;
++ u32 rx_clock_edge;
++};
+
-+ unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
-+ unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
-+ 0, parit32_1 = 0, parit32_2 = 0;
-+ unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
-+ 0, parit256_1 = 0, parit256_2 = 0;
-+ unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
-+ 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++#define RX_ENABLE_MASK 0x00000001
++#define RX_FIFO_ENABLE_MASK 0x00000002
++#define RX_FRAME_SYNC_MASK 0x00000004
++#define DIRECT_COMPANDING_MASK 0x00000008
++#define RX_SYNC_SEL_MASK 0x00000010
++#define RX_CLK_POL_MASK 0x00000020
++#define RX_CLK_SEL_MASK 0x00000040
++#define LOOPBACK_MASK 0x00000080
++#define TX_ENABLE_MASK 0x00000100
++#define TX_FIFO_ENABLE_MASK 0x00000200
++#define TX_FRAME_SYNC_MASK 0x00000400
++#define TX_SYNC_SEL_MASK 0x00001800
++#define TX_CLK_POL_MASK 0x00002000
++#define TX_CLK_SEL_MASK 0x00004000
++#define TX_EXTRA_DELAY_MASK 0x00008000
++#define SRG_ENABLE_MASK 0x00010000
++#define SRG_CLK_POL_MASK 0x00020000
++#define SRG_CLK_SEL_MASK 0x000C0000
++#define FRAME_GEN_EN_MASK 0x00100000
++#define SPI_CLK_MODE_MASK 0x00600000
++#define SPI_BURST_MODE_MASK 0x00800000
+
-+ for (i = ecc_n_bytes - 1; i >= 0; --i) {
-+ datum = data[i];
-+ sumCol ^= datum;
-+ temp = lookup_t[datum];
++#define RXEN_BIT 0
++#define RFFEN_BIT 1
++#define RFSPOL_BIT 2
++#define DCM_BIT 3
++#define RFSSEL_BIT 4
++#define RCKPOL_BIT 5
++#define RCKSEL_BIT 6
++#define LBM_BIT 7
++#define TXEN_BIT 8
++#define TFFEN_BIT 9
++#define TFSPOL_BIT 10
++#define TFSSEL_BIT 11
++#define TCKPOL_BIT 13
++#define TCKSEL_BIT 14
++#define TXDDL_BIT 15
++#define SGEN_BIT 16
++#define SCKPOL_BIT 17
++#define SCKSEL_BIT 18
++#define FGEN_BIT 20
++#define SPICKM_BIT 21
+
-+ if (i & 0x01)
-+ parit8_1 ^= temp;
-+ if (i & 0x02)
-+ parit16_1 ^= temp;
-+ if (i & 0x04)
-+ parit32_1 ^= temp;
-+ if (i & 0x08)
-+ parit64_1 ^= temp;
-+ if (i & 0x10)
-+ parit128_1 ^= temp;
-+ if (i & 0x20)
-+ parit256_1 ^= temp;
-+ if (i & 0x40)
-+ parit512_1 ^= temp;
-+ if (i & 0x80)
-+ parit1024_1 ^= temp;
-+ if (i & 0x100)
-+ parit2048_1 ^= temp;
-+ }
++#define msp_rx_clkpol_bit(n) ((n & 1) << RCKPOL_BIT)
++#define msp_tx_clkpol_bit(n) ((n & 1) << TCKPOL_BIT)
++#define msp_spi_clk_mode_bits(n) ((n & 3) << SPICKM_BIT)
+
-+ glob_parity = lookup_t[sumCol];
+
-+ parit1_1 =
-+ ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
-+ parit1_2 =
-+ ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
-+ parit2_1 =
-+ ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+ parit2_2 =
-+ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
-+ parit4_1 =
-+ ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+ parit4_2 =
-+ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++/* Use this to clear the clock mode bits to non-spi */
++#define MSP_NON_SPI_CLK_MASK 0x00600000
+
-+ parit8_2 = glob_parity ^ parit8_1;
-+ parit16_2 = glob_parity ^ parit16_1;
-+ parit32_2 = glob_parity ^ parit32_1;
-+ parit64_2 = glob_parity ^ parit64_1;
-+ parit128_2 = glob_parity ^ parit128_1;
-+ parit256_2 = glob_parity ^ parit256_1;
-+ parit512_2 = glob_parity ^ parit512_1;
-+ parit1024_2 = glob_parity ^ parit1024_1;
-+ parit2048_2 = glob_parity ^ parit2048_1;
++#define P1ELEN_BIT 0
++#define P1FLEN_BIT 3
++#define DTYP_BIT 10
++#define ENDN_BIT 12
++#define DDLY_BIT 13
++#define FSIG_BIT 15
++#define P2ELEN_BIT 16
++#define P2FLEN_BIT 19
++#define P2SM_BIT 26
++#define P2EN_BIT 27
+
-+ /* Pack bits */
-+ ecc[0] =
-+ ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
-+ (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
-+ << 1) |
-+ parit8_2);
-+ ecc[1] =
-+ ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
-+ (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
-+ (parit128_1 << 1) | parit128_2);
-+ ecc[2] =
-+ ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
-+ (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
-+ << 1) |
-+ parit2048_2);
++#define msp_p1_elem_len_bits(n) (n & 0x00000007)
++#define msp_p2_elem_len_bits(n) (((n) << P2ELEN_BIT) & 0x00070000)
++#define msp_p1_frame_len_bits(n) (((n) << P1FLEN_BIT) & 0x00000378)
++#define msp_p2_frame_len_bits(n) (((n) << P2FLEN_BIT) & 0x03780000)
++#define msp_data_delay_bits(n) (((n) << DDLY_BIT) & 0x00003000)
++#define msp_data_type_bits(n) (((n) << DTYP_BIT) & 0x00000600)
++#define msp_p2_start_mode_bit(n) (n << P2SM_BIT)
++#define msp_p2_enable_bit(n) (n << P2EN_BIT)
+
-+ return 0;
-+}
++/* Flag register
++--------------------*/
++#define RX_BUSY 0x00000001
++#define RX_FIFO_EMPTY 0x00000002
++#define RX_FIFO_FULL 0x00000004
++#define TX_BUSY 0x00000008
++#define TX_FIFO_EMPTY 0x00000010
++#define TX_FIFO_FULL 0x00000020
+
-+static struct nand_ecclayout nand_oob = {
++#define RBUSY_BIT 0
++#define RFE_BIT 1
++#define RFU_BIT 2
++#define TBUSY_BIT 3
++#define TFE_BIT 4
++#define TFU_BIT 5
+
-+ .eccbytes = 12,
++/* Multichannel control register
++---------------------------------*/
++#define RMCEN_BIT 0
++#define RMCSF_BIT 1
++#define RCMPM_BIT 3
++#define TMCEN_BIT 5
++#define TNCSF_BIT 6
+
++/* Sample rate generator register
++------------------------------------*/
++#define SCKDIV_BIT 0
++#define FRWID_BIT 10
++#define FRPER_BIT 16
+
++#define SCK_DIV_MASK 0x0000003FF
++#define frame_width_bits(n) (((n) << FRWID_BIT) &0x0000FC00)
++#define frame_period_bits(n) (((n) << FRPER_BIT) &0x1FFF0000)
+
-+ .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
-+ .oobavail = MTD_NANDECC_AUTOPLACE,
-+ .oobfree = {
-+ { .offset = 8,
-+ .length = 8,
-+ },
-+ },
-+};
+
-+static struct mtd_partition nandflash_main_partitions[] = {
++/* DMA controller register
++---------------------------*/
++#define RX_DMA_ENABLE 0x00000001
++#define TX_DMA_ENABLE 0x00000002
+
-+ {.name = "X-Loader(NAND)",
-+ .offset = 0,
-+ .size = 2 * 0x000020000}, /*256 Kbytes */
-+ {.name = "MemInit(NAND)",
-+ .offset = 2 * 0x000020000,
-+ .size = 2 * 0x000020000}, /*128 KBytes */
-+ {.name = "BootLoader(NAND)",
-+ .offset = 4 * 0x000020000,
-+ .size = 16 * 0x00020000}, /*2Mbytes */
-+ {.name = "Kernel zImage(NAND)",
-+ .offset = 20 * 0x000020000,
-+ .size = 24 * 0x000020000}, /*3Mbytes */
-+ {.name = "Root Filesystem(NAND)",
-+ .offset = 44 * 0x000020000,
-+ .size = 176 * 0x000020000}, /*22 Mbytes */
-+ {.name = "User Filesystem(NAND)",
-+ .offset = 220 * 0x000020000,
-+ .size = 800 * 0x000020000}, /*100 Mbytes */
-+};
++#define RDMAE_BIT 0
++#define TDMAE_BIT 1
+
-+uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++/*Interrupt Register
++-----------------------------------------*/
++#define RECEIVE_SERVICE_INT 0x00000001
++#define RECEIVE_OVERRUN_ERROR_INT 0x00000002
++#define RECEIVE_FRAME_SYNC_ERR_INT 0x00000004
++#define RECEIVE_FRAME_SYNC_INT 0x00000008
++#define TRANSMIT_SERVICE_INT 0x00000010
++#define TRANSMIT_UNDERRUN_ERR_INT 0x00000020
++#define TRANSMIT_FRAME_SYNC_ERR_INT 0x00000040
++#define TRANSMIT_FRAME_SYNC_INT 0x00000080
++#define ALL_INT 0x000000ff
+
-+struct nand_bbt_descr bbt_desc = {
-+ .options = 0,
-+ .offs = 0,
-+ .len = 2,
-+ .pattern = scan_ff_pattern
-+};
++/* Protocol configuration values
++* I2S: Single phase, 16 bits, 2 words per frame
++-----------------------------------------------*/
++#define I2S_PROTOCOL_DESC \
++{ \
++ MSP_SINGLE_PHASE, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_ELEM_LENGTH_32, \
++ MSP_ELEM_LENGTH_32, \
++ MSP_DELAY_1, \
++ MSP_FALLING_EDGE, \
++ MSP_FALLING_EDGE \
++}
+
-+static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
-+ unsigned int ctrl)
-+{
-+ struct nomadik_nand_info *drvdata =
-+ container_of(mtd, struct nomadik_nand_info, mtd);
++/* Companded PCM: Single phase, 8 bits, 1 word per frame
++--------------------------------------------------------*/
++#define PCM_COMPAND_PROTOCOL_DESC \
++{ \
++ MSP_SINGLE_PHASE, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_ELEM_LENGTH_8, \
++ MSP_ELEM_LENGTH_8, \
++ MSP_DELAY_0, \
++ MSP_RISING_EDGE, \
++ MSP_FALLING_EDGE \
++}
+
-+ if (cmd == NAND_CMD_NONE)
-+ return;
++/* AC97: Double phase, 1 element of 16 bits during first phase,
++* 12 elements of 20 bits in second phase.
++--------------------------------------------------------------*/
++#define AC97_PROTOCOL_DESC \
++{ \
++ MSP_DUAL_PHASE, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_FRAME_LENGTH_12, \
++ MSP_ELEM_LENGTH_16, \
++ MSP_ELEM_LENGTH_20, \
++ MSP_DELAY_1, \
++ MSP_RISING_EDGE, \
++ MSP_FALLING_EDGE \
++}
+
-+ if (ctrl & NAND_NCE) {
-+ *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
-+ 0x40)) |= 0x04;
-+ }
-+ if (ctrl & NAND_CLE) {
-+ writeb(cmd,drvdata->cmemc_va);
-+ }
-+ if (ctrl & NAND_ALE) {
-+ writeb(cmd,drvdata->cmema_va);
-+ }
++#define SPI_MASTER_PROTOCOL_DESC \
++{ \
++ MSP_SINGLE_PHASE, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_ELEM_LENGTH_8, \
++ MSP_ELEM_LENGTH_8, \
++ MSP_DELAY_1, \
++ MSP_FALLING_EDGE, \
++ MSP_RISING_EDGE \
++}
++#define SPI_SLAVE_PROTOCOL_DESC \
++{ \
++ MSP_SINGLE_PHASE, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_FRAME_LENGTH_1, \
++ MSP_ELEM_LENGTH_8, \
++ MSP_ELEM_LENGTH_8, \
++ MSP_DELAY_1, \
++ MSP_FALLING_EDGE, \
++ MSP_RISING_EDGE \
+}
++#define FUNC_MSP0 GPIO_ALT_MSP_0
++#define FUNC_MSP1 GPIO_ALT_MSP_1
++#define FUNC_MSP2 GPIO_ALT_MSP_2
+
-+static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
-+ .parts = nandflash_main_partitions,
-+ .num_parts = ARRAY_SIZE(nandflash_main_partitions),
-+ .lp_options = NAND_STM_LP_OPTIONS,
-+ .eccsize = 512,
-+ .eccsteps = 4,
-+ .badblockpos = 5,
-+ .init = nomadik_nandflash_init,
-+ .exit = nomadik_nandflash_exit,
-+ .nand_oob = &nand_oob,
-+ .bbt_desc = &bbt_desc,
-+ .compute_ecc = nmdknand_compute_ecc512,
-+ .hwcontrol = nmdknand_hwcontrol,
-+};
++#define MSP_FRAME_PERIOD_IN_MONO_MODE 256
++#define MSP_FRAME_PERIOD_IN_STEREO_MODE 32
++#define MSP_FRAME_WIDTH_IN_STEREO_MODE 16
+
-+static struct platform_device nomadik_nand_flash = {
-+ .name = "NOMADIK-NAND",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &nomadik_nand_flash_data,
-+ },
-+ .num_resources = ARRAY_SIZE(nandflash_resources),
-+ .resource = nandflash_resources,
-+};
++#define MSP_COUNT 3
+
-+static struct mtd_partition nmdkflash_main_partitions[] = {
-+ {.name = "BootLoader(NOR)",
-+ .size = 0x00040000, /*256K */
-+ .offset = 0,},
-+ {.name = "zImage+initrd(NOR)",
-+ .size = 0x001C0000, /*1.75MB */
-+ .offset = MTDPART_OFS_APPEND,},
-+ {.name = "Root Filesystem(NOR)",
-+ .size = 0x01200000, /*18MB */
-+ .offset = MTDPART_OFS_APPEND,},
-+ {.name = "User Filesystem(NOR)",
-+ .size = 0x00800000, /*8MB */
-+ .offset = MTDPART_OFS_APPEND,},
-+ {.name = "initrd(NOR)",
-+ .size = 0x00200000, /*4MB */
-+ .offset = MTDPART_OFS_APPEND,}
-+};
++#endif
+
-+static struct flash_platform_data nomadik_nor_flash_data = {
-+ .name = "nomadik_nor",
-+ .map_name = "cfi_probe",
-+ /*.width = NMDK_FLASH_BUSWIDTH, */
-+ .parts = nmdkflash_main_partitions,
-+ .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
-+};
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/mtu.c
+@@ -0,0 +1,589 @@
++/*
++ * Multiple Timer Unit (MTU) driver.
++ * Written by Vinayak Pane <vinayak.pane@st.com>
++ *
++ * Nomadik MTU driver.
++ *
++ * This driver provides an interface for device drivers to utilize both MTUs.
++ * which includes total 8 timers, Those can be registered against various purposes
++ * within kernel.
++ * It keeps track of used & unused timer units. It handles MTU interrupts
++ * & their respective multiplexing.
++ *
++ * NOTE:
++ * This device is NOT registered with amba bus device -:
++ * Even though this driver should be registered with AMBA bus devices,
++ * we cant do this becasue of Amba driver initialised/probed sequence issue.
++ * MTU is used as underlying part of system timer. The system timer
++ * is initialised and used very early before the actual Amba devices
++ * are initialised/probed. Therefore this probe function is not invoked
++ * before the system timer is initialised!!
++ * However we can catergories this driver in platform/system drivers.
++ */
+
-+static struct resource norflash_resources[] = {
-+ [0] = {
-+ .name = "norflash-regs",
-+ .start = NMDK_FLASH_BASE,
-+ .end = (NMDK_FLASH_BASE + SZ_32M - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+};
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/device.h>
+
-+static struct platform_device nomadik_nor_flash = {
-+ .name = "NOMADIK-NOR",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &nomadik_nor_flash_data,
-+ },
-+ .num_resources = ARRAY_SIZE(norflash_resources),
-+ .resource = norflash_resources,
-+};
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++#include <asm/arch/timex.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/mtu.h>
+
++#ifdef DEBUG_MTU
++#define dbg_mtu(format, arg...) printk(KERN_WARNING "" format "\n", ##arg)
++#else
++#define dbg_mtu(format, arg...) do { } while (0)
+#endif
+
-+#undef NMDK_DEBUG /*board*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
++static irqreturn_t(*mtu_irqs[MTU_MAX_TIMERS + 1]) (mtu_timer_t timer_id) = {
++NULL};
++unsigned char mtu_inuse = 0;
++static spinlock_t mtu_inuse_lock;
+
++static spinlock_t mtu0_spinlock, mtu1_spinlock;
+
-+#ifdef CONFIG_SMC91X
-+static void nomadik_smc91x_irq_init(void)
++ /* functions to read/write control registers */
++static inline unsigned long mtu_readl(unsigned int timer,
++ unsigned long ctrl_register)
+{
-+ /* Reset ethernet controller */
-+ nomadik_epio_write_aux_gpo1(nomadik_epio_read_aux_gpo1() &
-+ (unsigned long)(~LAN_RST));
-+ /* Enabling ethernet interrupts */
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)(~GPIO106_LAN_IT));
-+ /*type need to be set in case of shared irq */
-+ set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING);
++ unsigned long value, r_address = MTU_CTRL_REG(timer, ctrl_register);
++ value = readl(r_address);
++ return value;
+}
+
-+static struct resource smc91x_resources[] = {
-+ [0] = {
-+ .name = "smc91x-regs",
-+ .start = (NOMADIK_ETH0_BASE + 0x300),
-+ .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .start = IRQNO_GPIO(SMC91111_IRQ),
-+ .end = IRQNO_GPIO(SMC91111_IRQ),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device smc91x_device = {
-+ .name = "smc91x",
-+ .id = 0,
-+ .num_resources = ARRAY_SIZE(smc91x_resources),
-+ .resource = smc91x_resources,
-+};
-+#endif
-+
-+/*
-+ * touchpanel
-+ */
-+#ifdef CONFIG_TOUCHSCREEN_NOMADIK
-+#ifndef TOUCHP_DEBUG
-+#define TOUCHP_DEBUG 0 /* default debug messages are disabled */
-+#endif /* */
-+
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */
-+#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++static inline void mtu_writel(unsigned int timer, long value,
++ unsigned long ctrl_register)
++{
++ unsigned long w_address = MTU_CTRL_REG(timer, ctrl_register);
++ writel(value, w_address);
++}
+
-+/**
-+ * nomadik_tp_ssp_board_init - board specific ssp data path setup
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine initializes the SSP for touchpanel operation
-+ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
-+ */
-+int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
++ /* functions to read/write interrupt registers */
++inline unsigned long mtu_intr_reg_readl(unsigned int timer,
++ unsigned long ctrl_register)
+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_ssp_conf(EXP_SSP);
-+ return (0);
++ unsigned long value, r_address = MTU_INTR_REG(timer, ctrl_register);
++ value = readl(r_address);
++ return value;
+}
+
-+/**
-+ * nomadik_tp_gpio_board_init - board specific gpio initialization
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine initializes the GPIO for touchpanel operation
-+ * RETURN: GPIO nmdk_error code
-+ * SSP is interfaced with ADS7843 through CPLD hence respective
-+ * interface need to be enabled for NDK10
-+ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
-+ * chip select, this bit allows the selection between the two
-+ * peripherals. setting this bit Touch screen selected
-+ */
-+gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
++static inline void mtu_intr_reg_writel(unsigned int timer, long value,
++ unsigned long ctrl_register)
+{
-+ gpio_error status = GPIO_OK;
++ unsigned long w_address = MTU_INTR_REG(timer, ctrl_register);
++ writel(value, w_address);
++}
+
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
++static
++void mtu_set_timer_mode(mtu_timer_t timer, mtu_timer_mode_t mode)
++{
++ unsigned long timer_cr = 0;
+
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+ {
-+ gpio_config config_cspin;
-+ /* Set SPICSn_TCHSCR pin configuration */
-+ config_cspin.mode = GPIO_MODE_SOFTWARE;
-+ config_cspin.direction = GPIO_DIR_OUTPUT;
-+ config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
-+ config_cspin.dev_name = "Touchp";
-+ status = nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
-+ if (status) {
-+ nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
-+ TOUCHP_CS0, status);
-+ goto err_TOUCHP_CS0;
-+ }
++ timer_cr = mtu_readl(timer, TyCR); /* read original control register */
++ switch (mode) {
++ case MTU_PERIODIC:
++ timer_cr &= ~MTU_ONE_SHOT; /* clear the one-shot mode */
++ timer_cr = timer_cr | MTU_PERIODIC;
++ break;
+
-+ status = nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
-+ if (status) {
-+ nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
-+ TOUCHP_CS1, status);
-+ goto err_TOUCHP_CS1;
-+ }
++ case MTU_FREE_RUN:
++ timer_cr = timer_cr & MTU_FREE_RUN;
++ break;
++ case MTU_ONE_SHOT:
++ timer_cr = timer_cr | MTU_ONE_SHOT;
++ break;
+ }
-+#endif
-+ /* Set PENIRQ pin configuration */
-+ set_irq_type(p_adsContext->irq, SA_TRIGGER_FALLING);
++ mtu_writel(timer, timer_cr, TyCR); /* write back CR */
++ dbg_mtu("MTU: timer_mode : after CR = %ld\n", timer_cr);
++}
+
-+ return status;
++#define TyEN 0x0080
++static int mtu_enable_timer(mtu_timer_t timer)
++{
++ unsigned long timer_cr = 0;
++ if (timer > MTU_MAX_TIMERS)
++ return -1;
++ timer_cr = mtu_readl(timer, TyCR);
++ timer_cr |= TyEN;
++ mtu_writel(timer, timer_cr, TyCR);
++ dbg_mtu("MTU: After enable timer CR = %ld\n", timer_cr);
++ return 0;
++}
+
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+ err_TOUCHP_CS1:
-+ nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
-+ err_TOUCHP_CS0:
-+ return status;
-+#endif
++static void mtu_disable_timer(mtu_timer_t timer)
++{
++ unsigned long timer_cr;
++ timer_cr = mtu_readl(timer, TyCR);
++ timer_cr &= ~(unsigned long)TyEN;
++ mtu_writel(timer, timer_cr, TyCR);
+}
+
-+/**
-+ * nomadik_tp_gpio_board_exit - board specific gpio exit
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine performs revers action of init
-+ */
-+gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
++#define TySZ 0x0002
++static int mtu_change_counter_size(mtu_timer_t timer)
+{
-+ gpio_error status = GPIO_OK;
++ /* by default the timer counter is 16-bit only,
++ we can change its size to 32-bit here. */
+
-+ nmdk_dbg_ftrace();
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+ status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
-+ status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
-+#endif
-+ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
-+ return status;
++ unsigned long timer_cr = 0;
++ timer_cr = mtu_readl(timer, TyCR);
++ timer_cr |= TySZ;
++ mtu_writel(timer, timer_cr, TyCR);
++ dbg_mtu("MTU: after change_counter_size CR = %ld\n", timer_cr);
++ return 0;
+}
+
-+/**
-+ * nomadik_tp_pen_down - returns pen touch status
-+ */
-+t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
++#define DIVIDE_BY_ONE 0xfffffff3
++#define DIVIDE_BY_SIXTEEN 0x00000004
++#define DIVIDE_BY_256 0x00000008
++
++static int mtu_change_timer_prescaler(unsigned int timer,
++ mtu_prescale_t prescaler_factor)
+{
-+ gpio_data pen_down;
++ unsigned long timer_prescaler = 0;
++ timer_prescaler = mtu_readl(timer, TyCR);
+
-+ nmdk_dbg_ftrace();
-+ nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
-+ nmdk_dbg2("pen_down = 0x%d (pin%d)",
-+ pen_down, GPIO_PIN_FOR_IRQ(p_adsContext->irq));
-+ return ((t_bool) pen_down);
++ switch (prescaler_factor) {
++ case MTU_PRESCALE_BY_ONE:
++ timer_prescaler &= DIVIDE_BY_ONE;
++ break;
++ case MTU_PRESCALE_BY_SIXTEEN:
++ timer_prescaler &= DIVIDE_BY_ONE; /* reset first */
++ timer_prescaler |= DIVIDE_BY_SIXTEEN; /* set it to 01b now */
++ break;
++ case MTU_PRESCALE_BY_256:
++ timer_prescaler &= DIVIDE_BY_ONE;
++ timer_prescaler |= DIVIDE_BY_256;
++ break;
++ }
++ mtu_writel(timer, timer_prescaler, TyCR);
++ return 0;
+}
-+
-+/**
-+ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
++unsigned long mtu_get_decrementing_counter_value(mtu_timer_t timer)
+{
-+ nmdk_dbg_ftrace();
-+ enable_irq(p_adsContext->irq);
++ unsigned long decrementing_counter = 0;
++ decrementing_counter = mtu_readl(timer, TyVAL);
++ return decrementing_counter;
+}
+
-+/**
-+ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
++EXPORT_SYMBOL(mtu_get_decrementing_counter_value);
++
++static inline void mtu_load_counter(mtu_timer_t timer,
++ unsigned long timer_load_register)
+{
-+ nmdk_dbg_ftrace();
-+ disable_irq(p_adsContext->irq);
++ mtu_writel(timer, timer_load_register, TyLR);
+}
+
-+/**
-+ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
-+ *
-+ * sets GPIOS to to provid inputs to CPLD to disable chip select
-+ */
-+void nomadik_tp_spi_cs_disable(void)
++inline void mtu_bg_load_counter(mtu_timer_t timer,
++ unsigned long timer_load_register)
+{
-+ nmdk_dbg_ftrace();
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+ nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
-+ nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
-+#endif
++ mtu_writel(timer, timer_load_register, TyBGLR);
+}
+
-+/**
-+ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
-+ *
-+ * sets GPIOS to to provid inputs to CPLD to enable chip select
-+ */
-+void nomadik_tp_spi_cs_enable(void)
++EXPORT_SYMBOL(mtu_bg_load_counter);
++
++/***************************************************************
++ * functiion : mtu0_timer_interrupt_handler
++ * Description:
++ * Interrupt of MTU Unit 0 is handled.
++ * With the priority as MTU0_T0, MTU0_T1,
++ * MTU0_T2, MTU0_T3. And then the corrosponding
++ * timer unit's interrupt handler will be called.
++ * Returns:
++ * IRQ_HANDLED - ret val from the sub-irq
++ * IRQ_HANDLED - if the corrosponding irq is not present.
++ ****************************************************************/
++
++static irqreturn_t mtu0_timer_interrupt_handler(int irq, void *dev_id)
+{
-+ nmdk_dbg_ftrace();
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+ nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
-+ nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
-+#endif
-+}
++ unsigned long status;
++ unsigned long icr_flag = 0;
++ mtu_timer_t timer = 0;
+
-+static struct touchp_device touchp_board = {
-+ .ssp_init = nomadik_tp_ssp_board_init,
-+ .gpio_init = nomadik_tp_gpio_board_init,
-+ .gpio_exit = nomadik_tp_gpio_board_exit,
-+ .pdown = nomadik_tp_pen_down,
-+ .pirq_en = nomadik_tp_pen_down_irq_enable,
-+ .pirq_dis = nomadik_tp_pen_down_irq_disable,
-+ .cs_en = nomadik_tp_spi_cs_disable,
-+ .cs_dis = nomadik_tp_spi_cs_enable,
-+ .samples = 100, /*samples per second*/
-+ .pollsamples = 10, /*polling per second*/
-+};
++ spin_lock(&mtu0_spinlock);
++ status = mtu_intr_reg_readl(MTU0_T0, TxRIS);
++ timer = ffs(status);
++ if ( timer != 1)
++ {
++ icr_flag |= 1UL << (timer - 1);
++ mtu_intr_reg_writel(timer, icr_flag, TxICR); /* clear ICR bit */
++ }
++ spin_unlock(&mtu0_spinlock);
+
-+static struct resource touchp_resources[] = {
-+ [0] = {
-+ .start = IRQNO_GPIO(TOUCHP_IRQ),
-+ .end = IRQNO_GPIO(TOUCHP_IRQ),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
++ if (likely(mtu_irqs[timer]))
++ return mtu_irqs[timer] (timer);
++ else {
++ dbg_mtu("MTU0:Interrupt on this timer[%d] is not handled.\n",
++ timer);
++ return IRQ_HANDLED;
++ }
+
-+static struct platform_device touchp_device = {
-+ .name = "nmdk-tp",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &touchp_board,
-+ },
-+ .num_resources = ARRAY_SIZE(touchp_resources),
-+ .resource = touchp_resources,
-+};
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#endif
++ return IRQ_HANDLED;
++}
+
-+#ifdef CONFIG_KEYPAD_NOMADIK
-+#define KEYPAD_NAME "KEYPAD"
-+#ifndef KEYPAD_DEBUG
-+#define KEYPAD_DEBUG 0
-+#endif
++static irqreturn_t mtu1_timer_interrupt_handler(int irq, void *dev_id)
++{
++ unsigned long status;
++ unsigned long icr_flag = 0;
++ mtu_timer_t timer = 0;
+
-+#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++ spin_lock(&mtu1_spinlock);
++ status = mtu_intr_reg_readl(MTU1_T0, TxRIS);
++ /* which timer the interrupt is for */
++ timer = ffs(status);
++ icr_flag |= 1UL << (timer - 1);
++ timer = timer + 4;
++ mtu_intr_reg_writel(timer, icr_flag, TxICR); /* clear ICR bit */
+
-+/*key scan constants*/
-+#define KSCAN_ALLROWS 0x00FF
-+#define KSCAN_ALLCOLS 0xFF00
-+#define KSCAN_ROW0 0x0001
-+#define KSCAN_ROW1 0x0002
-+#define KSCAN_ROW2 0x0004
-+#define KSCAN_ROW3 0x0008
-+#define KSCAN_ROW4 0x0010
-+#define KSCAN_ROW5 0x0020
-+#define KSCAN_ROW6 0x0040
-+#define KSCAN_ROW7 0x0080
-+#define KSCAN_COL0 0x0100
-+#define KSCAN_COL1 0x0200
-+#define KSCAN_COL2 0x0400
-+#define KSCAN_COL3 0x0800
-+#define KSCAN_COL4 0x1000
-+#define KSCAN_COL5 0x2000
-+#define KSCAN_COL6 0x4000
-+#define KSCAN_COL7 0x8000
++ spin_unlock(&mtu1_spinlock);
++ /* call corrsponding Irq handler */
++ if (likely(mtu_irqs[timer]))
++ return mtu_irqs[timer] (timer);
++ else {
++ dbg_mtu("MTU1:Interrupt on this timer[%d] is not handled.\n",
++ timer);
++ return IRQ_HANDLED;
++ }
+
-+unsigned short const keychkval_set[] = {
-+ (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
-+ (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++ return IRQ_HANDLED;
++}
++
++struct irqaction mtu0_timer_irq = {
++ .name = "MTU0 Timer Tick",
++ .flags = SA_INTERRUPT | IRQF_TIMER,
++ .handler = mtu0_timer_interrupt_handler,
++ .dev_id = NULL,
+};
+
-+unsigned short const keychkval_read[] = {
-+ KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
-+ KSCAN_ROW6, KSCAN_ROW7,
++struct irqaction mtu1_timer_irq = {
++ .name = "MTU1 Timer Tick",
++ .flags = SA_INTERRUPT | IRQF_TIMER,
++ .handler = mtu1_timer_interrupt_handler,
++ .dev_id = NULL,
+};
+
-+/**
-+ * nomadik_kp_ghostkey_detect - ghost key detect function
-+ * @rowval: row in which ghost key to be detected
-+ *
-+ * when more than one key is pressed in the same row the keypad logic cannot
-+ * detect proper key press, the logic here detects multiple keypress on a
-+ * single row and returns error
-+ */
-+int nomadik_kp_ghostkey_detect(short rowval)
++static int mtu_irq_initialize(mtu_timer_t timer,
++ irqreturn_t(*mtu_sub_irq) (mtu_timer_t timer_id))
+{
-+ int row;
-+ int ghcnt = 0;
++ unsigned long icr_flag = 0, clean_icrs = 0;
++ unsigned long imsc = 0;
++ unsigned long flags;
+
-+ for (row = 0; row < MAX_KPROW; row++) {
-+ if (0 == (rowval & keychkval_read[row])) {
-+ /*keypr detected */
-+ ghcnt++;
-+ }
-+ if (1 < ghcnt)
-+ /*return error if more than one keys are pressed in a row */
-+ return (-1);
-+ }
-+ return (0);
-+}
++ if (mtu_sub_irq == NULL)
++ return -1;
+
-+/**
-+ * nomadik_kp_key_scan - keypad scan and report event function
-+ *
-+ * Scans through keypad hardware and updates the key status for key press
-+ * or key release event to upper layer
-+ */
-+int nomadik_kp_key_scan(struct keypad_t *kp)
-+{
-+ short val;
-+ u8 row, col;
-+ int keyp_cnt = 0;
-+ u8 *p_kcode;
++ spin_lock(&mtu_inuse_lock);
++ /* make sure that unregistered timer interrupts are cleared
++ icr_flag = mtu_intr_reg_readl(timer, TxICR);
++ : returns Zero always. */
++ if (timer > 4)
++ clean_icrs = mtu_inuse >> 4;
++ else
++ clean_icrs = mtu_inuse;
++ /* register the irq sub-handler */
++ mtu_irqs[timer] = mtu_sub_irq;
++ spin_unlock(&mtu_inuse_lock);
+
-+ nmdk_dbg_ftrace();
-+ for (col = 0; col < MAX_KPCOL; col++) {
-+ p_kcode = kp->board->kcode_tbl + col;
-+ nomadik_epio_write_keypad(keychkval_set[col]);
-+ val = nomadik_epio_read_keypad();
-+ val &= KSCAN_ALLROWS;
-+ if (0 == nomadik_kp_ghostkey_detect(val)) {
-+ for (row = 0; row < MAX_KPROW; row++) {
-+ if (0 == (val & keychkval_read[row])) { /*keypr detected */
-+ keyp_cnt++;
-+ if (kp->key_state[row][col] ==
-+ KEYPAD_STATE_DEFAULT) {
-+ input_report_key(kp->inp_dev,
-+ *p_kcode, 1);
-+ nmdk_dbg("P:%d ", *p_kcode);
-+ kp->key_state[row][col] =
-+ KEYPAD_STATE_PRESSACK;
-+ }
-+ } else { /*key not pressed detected */
-+ if (kp->key_state[row][col] ==
-+ KEYPAD_STATE_PRESSACK) {
-+ input_report_key(kp->inp_dev,
-+ *p_kcode, 0);
-+ nmdk_dbg("R:%d ", *p_kcode);
-+ kp->key_state[row][col] =
-+ KEYPAD_STATE_DEFAULT;
-+ }
-+ }
-+ p_kcode += MAX_KPROW;
-+ }
-+ } else
-+ keyp_cnt += 0x100; /* to flag ghost keypress detection */
-+ }
-+ /* pull down all rows to detect any keypress */
-+ nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
-+ return (keyp_cnt);
-+}
++ /* the INTR bits/registers will be affected here */
++ if (timer > 4)
++ spin_lock_irqsave(&mtu1_spinlock, flags);
++ else
++ spin_lock_irqsave(&mtu0_spinlock, flags);
+
-+/**
-+ * nomadik_kp_init_key_hardware - keypad hardware initialization
-+ *
-+ * Initializes the keypad hardware specific parameters.
-+ * This function will be called by nomadik_keypad_init function during init
-+ * Initialize keypad interrupt handler for interrupt mode operation if enabled
-+ * Initialize Keyscan matrix
-+ ****************************************************************************
-+ */
-+int nomadik_kp_init_key_hardware(struct keypad_t *kp)
-+{
-+ nmdk_dbg_ftrace();
-+ nomadik_epio_write_keypad(KSCAN_ALLCOLS);
-+ if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
-+ /*check wrong key */
-+ nmdk_error("Keypad H/w error....");
-+ return (-1);
-+ }
-+ if (!kp->mode) { /* true if interrupt mode operation */
-+ /* pull down all rows to detect any keypress */
-+ nomadik_epio_write_keypad(KSCAN_ALLROWS);
-+ set_irq_type(kp->irq, SA_TRIGGER_FALLING);
-+ /*
-+ * TBD logic should be added to detect proper switch settings
-+ * on a board to detect valid interrupt
-+ */
-+ }
-+ return 0;
-+}
++ icr_flag = ~clean_icrs;
++ icr_flag |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
++ mtu_intr_reg_writel(timer, icr_flag, TxICR);
+
-+/**
-+ * nomadik_kp_exit_key_hardware- keypad hardware exit function
-+ *
-+ * This function will be called by nomadik_keypad_exit function during module
-+ * exit, frees keypad interrupt if enabled
-+ */
-+int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
-+{
-+ nmdk_dbg_ftrace();
-+ /* pull up all columns so that interrupt will not be raised*/
-+ nomadik_epio_write_keypad(KSCAN_ALLCOLS |KSCAN_ALLCOLS);
-+ return 0;
-+}
++ /* enable interrupt */
++ imsc = mtu_intr_reg_readl(timer, TxIMSC);
++ imsc |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
++ mtu_intr_reg_writel(timer, imsc, TxIMSC);
+
-+/**
-+ * nomadik_kp_key_irqen- enables keypad interrupt
-+ *
-+ * enables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqen(struct keypad_t *kp)
-+{
-+ /*enable_irq(kp->irq);*/
++ if (timer > 4)
++ spin_unlock_irqrestore(&mtu1_spinlock, flags);
++ else
++ spin_unlock_irqrestore(&mtu0_spinlock, flags);
+ return 0;
+}
+
-+/**
-+ * nomadik_kp_key_irqdis- disables keypad interrupt
-+ *
-+ * disables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqdis(struct keypad_t *kp)
++int mtu_register_timer(struct mtu_struct *mtu)
+{
-+ /*disable_irq(kp->irq);*/
-+ return 0;
-+}
++ u64 mtu_interval_ns;
++ mtu_prescale_t mtu_prescale;
++ if (mtu == NULL)
++ return -EINVAL;
++ if (mtu->timer > MTU_MAX_TIMERS)
++ return -EINVAL;
+
-+/*
-+ * Initializes the key scan table (lookup table) as per pre-defined the scan
-+ * codes to be passed to upper layer with respective key codes
-+ */
-+u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
-+ {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
-+ {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
-+ {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT,
-+ KEY_HOME},
-+ {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U},
-+ {KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH,
-+ KEY_DELETE, KEY_END},
-+ {KEY_CAPSLOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J},
-+ {KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, KEY_DOT,
-+ KEY_COMMA, KEY_SLASH},
-+ {KEY_LEFTSHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M}
-+};
++#ifndef CONFIG_NOMADIK_MTU_SYSTEM_TICK
++ /* if the MTU0 IRQ is not set here, we cant use the timers:
++ * MTU0_T0, MTU0_T1, MTU0_T2 & MTU0_T3
++ */
++ if (mtu->timer <= 4) {
++ printk(KERN_WARNING
++ "MTU: Can not register, since MTU0 support is absent.\n");
++ return -EINVAL;
++ }
++#endif
+
-+static struct keypad_device keypad_board = {
-+ .init = nomadik_kp_init_key_hardware,
-+ .exit = nomadik_kp_exit_key_hardware,
-+ .scan = nomadik_kp_key_scan,
-+ .irqen = nomadik_kp_key_irqen,
-+ .irqdis = nomadik_kp_key_irqdis,
-+ .kcode_tbl = (u8 *) kpd_lookup_tbl,
-+ .krow = 8,
-+ .kcol = 8,
-+};
++ spin_lock(&mtu_inuse_lock);
++ if (mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) {
++ printk(KERN_WARNING
++ "MTU: This timer unit is already in use.\n");
++ spin_unlock(&mtu_inuse_lock);
++ return -EBUSY;
++ } else {
++ mtu_inuse |= (unsigned char)0x1 << (mtu->timer - 1);
++ }
++ spin_unlock(&mtu_inuse_lock);
+
-+static struct resource keypad_resources[] = {
-+ [0] = {
-+ .start = IRQNO_GPIO(KEYPAD_IRQ),
-+ .end = IRQNO_GPIO(KEYPAD_IRQ),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
++ if (mtu->mtu_irq) {
++ mtu_irq_initialize(mtu->timer, mtu->mtu_irq);
++ } else {
++ printk(KERN_WARNING
++ "MTU: Must specify the action handler for timer.\n");
++ return -EINVAL;
++ }
+
-+static struct platform_device keypad_device = {
-+ .name = "nmdk-kp",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &keypad_board,
-+ },
-+ .num_resources = ARRAY_SIZE(keypad_resources),
-+ .resource = keypad_resources,
-+};
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#endif
++ mtu_set_timer_mode(mtu->timer, mtu->mode);
++ mtu_interval_ns = ktime_to_ns(mtu->interval);
+
-+#ifdef CONFIG_CPLD_I2C
-+#define EPIO_NAME "EPIO"
-+#ifndef EPIO_DEBUG
-+#define EPIO_DEBUG 0
++ /* calculate the timer load register value from ktime(sec,nsec) format */
++#if BITS_PER_LONG != 64
++ /* XXX the arithmatic part shall be replaced by ktime_ns-ops */
++ dbg_mtu("MTU: nano second interval passed is : %lld \n",
++ mtu_interval_ns);
++
++ if (mtu_interval_ns / USEC_PER_SEC < (0x6FA * MSEC_PER_SEC)) {
++ mtu_prescale = MTU_PRESCALE_BY_ONE;
++ mtu_interval_ns = mtu_interval_ns * 24 * MSEC_PER_SEC;
++ do_div(mtu_interval_ns, 10);
++ } else {
++ if (mtu_interval_ns / USEC_PER_SEC < (0xB2F * MSEC_PER_SEC)) {
++ mtu_prescale = MTU_PRESCALE_BY_SIXTEEN;
++ mtu_interval_ns = mtu_interval_ns * 15 * MSEC_PER_SEC;
++ do_div(mtu_interval_ns, 100);
++ } else {
++ mtu_prescale = MTU_PRESCALE_BY_256;
++ mtu_interval_ns = mtu_interval_ns * 93 * MSEC_PER_SEC;
++ do_div(mtu_interval_ns, 10000);
++ }
++ }
++
++ do_div(mtu_interval_ns, USEC_PER_SEC);
++
++ if (mtu_interval_ns >> 32) {
++ printk(KERN_WARNING
++ "MTU: The interval specified is too big to fit in reload value.\n");
++ spin_lock(&mtu_inuse_lock);
++ mtu_irqs[mtu->timer] = NULL;
++ spin_unlock(&mtu_inuse_lock);
++ return -EINVAL;
++ }
++
++ dbg_mtu("MTU: setting the prescaler of timer to [%x]\n", mtu_prescale);
++ mtu_change_timer_prescaler(mtu->timer, mtu_prescale);
++
++ if (mtu_interval_ns >> 16) {
++ dbg_mtu("MTU: changing the counter size to 32 bits\n");
++ mtu_change_counter_size(mtu->timer);
++ }
++
++ dbg_mtu("MTU:Using %lld as calculated interval for timer\n",
++ mtu_interval_ns);
++ /* lets ignore the LSB part now, MTU supports 32bit counter regi only */
++ mtu_load_counter(mtu->timer, mtu_interval_ns);
++
++ /* XXX: if BG-load-register is passed we have to calculate the
++ * mtu_bg_interval_ns load value and then load it. */
++ if (mtu->bg_interval.tv64 == mtu->interval.tv64) /* right now, this much is supported */
++ mtu_bg_load_counter(mtu->timer, mtu_interval_ns);
++
++ /* finally enable and start the timer */
++ mtu_enable_timer(mtu->timer);
++#else
++ printk(KERN_WARNING "MTU:Functionality is not implemented!\n");
+#endif
+
-+#define NMDK_DEBUG EPIO_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX EPIO_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
-+
-+static void nomadik_epio_plat_init(void)
++ return 0;
++}
++
++EXPORT_SYMBOL(mtu_register_timer);
++
++int mtu_unregister_timer(struct mtu_struct *mtu)
+{
-+ nmdk_dbg_ftrace();
-+ /* Initializing CPLD registers for initial values */
-+ nomadik_epio_write_cob_ctl(0x0030); /* reset value */
-+ nomadik_epio_write_keypad(0xff00); /* COL7:0 set to high Z */
-+ nomadik_epio_write_msp_conf(0x794); /* reset value */
-+ nomadik_epio_write_uart_conf(0x0694); /* UART1 enabled for rs232 port*/
-+ nomadik_epio_write_ssp_conf(0x0124); /* reset value */
-+ nomadik_epio_write_aux_gpo1(0x2880); /* reset value */
-+ nomadik_epio_write_aux_gpo2(0x018a); /* reset value */
-+#ifdef CONFIG_SMC91X
-+ nomadik_smc91x_irq_init();
-+#endif
++ unsigned long icr_clear = 0, imsc;
++ unsigned long flags;
++ icr_clear |=
++ 1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1));
++
++ spin_lock(&mtu_inuse_lock);
++
++ /* check if the caller has right to unregister this timer */
++ if (mtu->mtu_irq != mtu_irqs[mtu->timer]) {
++ unregister_failed:
++ spin_unlock(&mtu_inuse_lock);
++ return -EINVAL;
++ }
++
++ if ((mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) == 0) {
++ /* if the timer unit was not registered successfully */
++ goto unregister_failed;
++ } else
++ /* clear the inuse bit */
++ mtu_inuse &= ~((unsigned char)0x1 << (mtu->timer - 1));
++ spin_unlock(&mtu_inuse_lock);
++
++ if (mtu->timer > 4)
++ spin_lock_irqsave(&mtu1_spinlock, flags);
++ else
++ spin_lock_irqsave(&mtu0_spinlock, flags);
++
++ mtu_disable_timer(mtu->timer);
++
++ /* disable the interrupt */
++ imsc = mtu_intr_reg_readl(mtu->timer, TxIMSC);
++ imsc &=
++ ~(1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1)));
++ mtu_intr_reg_writel(mtu->timer, imsc, TxIMSC);
++
++ /* clear the interrupt of this timer */
++ mtu_intr_reg_writel(mtu->timer, icr_clear, TxICR);
++
++ mtu_load_counter(mtu->timer, 0);
++
++ spin_lock(&mtu_inuse_lock);
++ mtu_irqs[mtu->timer] = NULL;
++ spin_unlock(&mtu_inuse_lock);
++
++ if (mtu->timer > 4)
++ spin_unlock_irqrestore(&mtu1_spinlock, flags);
++ else
++ spin_unlock_irqrestore(&mtu0_spinlock, flags);
++
++ return 0;
+}
+
-+static struct platform_device epio_device = {
-+ .name = "NOMADIK-EPIO",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = nomadik_epio_plat_init,
-+ },
-+};
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#endif /*CONFIG_CPLD_I2C*/
++EXPORT_SYMBOL(mtu_unregister_timer);
+
-+static struct platform_device *nmdk_platform_devices[] __initdata = {
-+ &fsmc_device,
-+#ifdef CONFIG_CPLD_I2C
-+ &epio_device,
-+#endif
-+#ifdef CONFIG_KEYPAD_NOMADIK
-+ &keypad_device,
-+#endif
-+#ifdef CONFIG_SMC91X
-+ &smc91x_device,
-+#endif
-+#ifdef CONFIG_TOUCHSCREEN_NOMADIK
-+ &touchp_device,
-+#endif
-+#ifdef CONFIG_MTD
-+ &nomadik_nand_flash,
-+ &nomadik_nor_flash,
++static struct {
++ u32 tmr_value;
++ u32 tmr_control;
++ u32 tmr_bgload;
++}mtu_tmr_context[8];
++
++static u32 nomadik_mtu0_imsc[2];
++
++int nomadik_mtu_suspend(void)
++{
++ /* Use spin lock */
++ int inuse = mtu_inuse & ~1;
++ int tmr_no;
++
++ nomadik_mtu0_imsc[0] = mtu_intr_reg_readl(MTU0_T0, TxIMSC);
++ nomadik_mtu0_imsc[1] = mtu_intr_reg_readl(MTU1_T0, TxIMSC);
++ while(inuse)
++ {
++ tmr_no = ffs(inuse);
++ mtu_tmr_context[tmr_no-1].tmr_value = mtu_readl(tmr_no, TyVAL);
++ mtu_tmr_context[tmr_no-1].tmr_control = mtu_readl(tmr_no, TyCR);
++ mtu_tmr_context[tmr_no-1].tmr_bgload = mtu_readl(tmr_no, TyBGLR);
++ inuse = inuse & ~(1 << ( tmr_no - 1 ));
++ }
++ return 0;
++}
++
++int nomadik_mtu_resume(void)
++{
++ /* Use spin lock */
++ int inuse = mtu_inuse & ~1;
++ int tmr_no;
++
++ mtu_intr_reg_writel(MTU0_T0, nomadik_mtu0_imsc[0], TxIMSC);
++ mtu_intr_reg_writel(MTU1_T0, nomadik_mtu0_imsc[1], TxIMSC);
++ while(inuse)
++ {
++ tmr_no = ffs(inuse);
++ mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_value, TyLR);
++ mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_control, TyCR);
++ mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_bgload, TyBGLR);
++ inuse = inuse & ~(1 << ( tmr_no - 1 ));
++ }
++ return 0;
++}
++
++
++int __init nomadik_mtu_init(void)
++{
++ unsigned long all_icr_clear = 0xf;
++ volatile unsigned long *psrc_cr =
++ (volatile unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE);
++ unsigned long src_cr;
++ src_cr = *psrc_cr;
++ src_cr |= 0x2AAA8000;
++ *psrc_cr = src_cr;
++
++ spin_lock_init(&mtu0_spinlock);
++ spin_lock_init(&mtu1_spinlock);
++
++ mtu_irqs[0] = NULL;
++ /* clear the interrupts */
++
++ mtu_intr_reg_writel(MTU1_T0, all_icr_clear, TxICR);
++
++ /*
++ * setup an interrupt for the Timer units
++ */
++#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
++ /* Cannt use if module! It might screw the system "timer_tick" */
++ mtu_intr_reg_writel(MTU0_T0, all_icr_clear, TxICR);
++
++ setup_irq(IRQ_MTU0, &mtu0_timer_irq);
++ printk(KERN_INFO "MTU: Registered MTU0 timer unit.\n");
++
++ setup_irq(IRQ_MTU1, &mtu1_timer_irq);
++ printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
++#else
++ request_irq(IRQ_MTU1, mtu1_timer_irq.handler, mtu1_timer_irq.flags,
++ mtu1_timer_irq.name, NULL);
++ printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
+#endif
-+};
+
-+void add_nmdk_platform_devices(void)
++ return 0;
++}
++
++void __exit nomadik_mtu_exit(void)
+{
-+ platform_add_devices(nmdk_platform_devices,
-+ ARRAY_SIZE(nmdk_platform_devices));
++ mtu_timer_t timer;
++ /* disabling the registered timers */
++ while (mtu_inuse) {
++ timer = ffs(mtu_inuse);
++ mtu_disable_timer(timer);
++ mtu_inuse &= ~((unsigned char)0x1 << timer);
++ }
++
++ free_irq(IRQ_MTU1, NULL);
++
++#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
++ free_irq(IRQ_MTU0, NULL);
++#endif
+}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c 2008-09-17 13:23:32.000000000 +0530
-@@ -0,0 +1,1001 @@
++
++#ifndef CONFIG_MTU0
++module_init(nomadik_mtu_init);
++#endif
++module_exit(nomadik_mtu_exit);
++
++MODULE_LICENSE("Proprietary");
++MODULE_DESCRIPTION("Nomadik MTU Driver");
++MODULE_AUTHOR("ST Microelectronics");
++
++/* vim: set ts=4 noet sw=4 */
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig
+@@ -0,0 +1,28 @@
++if NOMADIK_NDK10_CUT_A1
++
++#target name configuration
++config NOMADIK_TARGET
++ string
++ default NDK10_Cut_A1
++
++# nomadik soc chip name configuration for this target
++config NOMADIK_SOC
++ string
++ default stn8810
++
++# nomadik platform name configuration for this target
++config NOMADIK_PLATFORM
++ string
++ default ndk10
++
++# EXTRA_CFLAGS configuration for this target
++config NOMADIK_TARGET_EXTRA_CFLAGS
++ string
++ default "-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++
++# Basic platform type configuration for this target (optional will be removed latter)
++config NOMADIK_NDK10
++ bool
++ default y
++
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig
+@@ -0,0 +1,35 @@
++if NOMADIK_NDK10_CUT_B06
++
++comment "Nomadik chip used STRn8810B2S12HPB cut B (chip secure)"
++
++#target name configuration for this target
++config NOMADIK_TARGET
++ string
++ default NDK10_Cut_B06
++
++# nomadik soc chip name configuration for this target
++config NOMADIK_SOC
++ string
++ default stn8810
++
++# nomadik soc chip cut name configuration for this targe only
++config NOMADIK_STRn8810B2S12HPB
++ bool
++ default y
++
++# nomadik platform name configuration for this target
++config NOMADIK_PLATFORM
++ string
++ default ndk10
++
++# EXTRA_CFLAGS configuration for this target
++config NOMADIK_TARGET_EXTRA_CFLAGS
++ string
++ default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++
++# Basic platform type configuration for this target
++config NOMADIK_NDK10
++ bool
++ default y
++
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig
+@@ -0,0 +1,35 @@
++if NOMADIK_NDK10_CUT_B0
++
++comment "Nomadik chip used STRn8810B2S12 cut B"
++
++#target name configuration for this target
++config NOMADIK_TARGET
++ string
++ default NDK10_Cut_B0
++
++# nomadik soc chip name configuration for this target
++config NOMADIK_SOC
++ string
++ default stn8810
++
++# nomadik soc chip cut name configuration for this targe only
++config NOMADIK_STRn8810B2S12
++ bool
++ default y
++
++# nomadik platform name configuration for this target
++config NOMADIK_PLATFORM
++ string
++ default ndk10
++
++# EXTRA_CFLAGS configuration for this target
++config NOMADIK_TARGET_EXTRA_CFLAGS
++ string
++ default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++
++# Basic platform type configuration for this target
++config NOMADIK_NDK10
++ bool
++ default y
++
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c
+@@ -0,0 +1,1225 @@
+/*
-+ * linux/arch/arm/mach-nomadik/ndk15_devices.c
-+ *
++ * linux/arch/arm/mach-nomadik/ndk10_devices.c
+ *
-+ * Copyright (C) STMicroelectronics
++ * Copyright (C) 2000-2003 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2, as
-+ * published by the Free Software Foundation.
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
+ *
-+ * NDK15B0x board specifc driver defination
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#endif
+#include <asm/arch/debug.h>
+
++/*
++ * epio
++ */
++#define EPIO_NAME "EPIO"
++
++#ifndef EPIO_DEBUG
++#define EPIO_DEBUG 0
++#endif
++
++#define NMDK_DEBUG EPIO_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX EPIO_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++static spinlock_t epio_cob_ctl_read = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_cob_ctl_write = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_kp_read = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_kp_write = SPIN_LOCK_UNLOCKED;
++
++static unsigned long epio_lgcl_addr_cob_ident_reg;
++static unsigned long epio_lgcl_addr_cob_ctl_reg;
++static unsigned long epio_lgcl_addr_kp_reg;
++static unsigned long epio_lgcl_addr_exp_ctrl_reg;
++static spinlock_t epio_exp_ctrl_read = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_exp_ctrl_write = SPIN_LOCK_UNLOCKED;
++
++/*
++ * nomadik_epio_read_cob_ident - reads COB_IDENT register of CPLD
++ *
++ * Reads the core bord version and CPLD version information stored in
++ * COB_IDENT register of CPLD on NDK10
++ */
++static short nomadik_epio_read_cob_ident(void)
++{
++ return ((short)
++ *((volatile unsigned short *)epio_lgcl_addr_cob_ident_reg));
++}
++
++/**
++ * nomadik_epio_read_cob_ctl - reads COB_CTL register of CPLD
++ *
++ * Reads the present value of the core-board-configuration register of CPLD
++ * on NDK10 board
++ */
++short nomadik_epio_read_cob_ctl(void)
++{
++ short i;
++
++ spin_lock(&epio_cob_ctl_read);
++ i = *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg);
++ spin_unlock(&epio_cob_ctl_read);
++ return (i);
++}
++
++/**
++ * nomadik_epio_write_cob_ctl - writes COB_CTL register of CPLD
++ * @expctrlval: value to be written
++ *
++ * Write the provided 16bit value into the core-board-configuration register
++ * of CPLD on NDK10 board
++ */
++void nomadik_epio_write_cob_ctl(unsigned short expctrlval)
++{
++ spin_lock(&epio_cob_ctl_write);
++ *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg) = expctrlval;
++ spin_unlock(&epio_cob_ctl_write);
++}
++
++/**
++ * nomadik_epio_read_keypad - reads KEYPAD register of CPLD
++ *
++ * Reads the present value of the keypad assignment register of CPLD on NDK10
++ */
++short nomadik_epio_read_keypad(void)
++{
++ short i;
++
++ spin_lock(&epio_kp_read);
++ i = (0x07FF & *((volatile unsigned short *)epio_lgcl_addr_kp_reg));
++ spin_unlock(&epio_kp_read);
++ return (i);
++}
++
++/**
++ * nomadik_epio_write_keypad - writes KEYPAD register of CPLD
++ * @keypadval: value to be written
++ *
++ * Writes the provided value to the keypad assignment reg of CPLD on NDK10
++ */
++void nomadik_epio_write_keypad(unsigned short kpdval)
++{
++ unsigned short i;
++
++ spin_lock(&epio_kp_write);
++ i = *((volatile unsigned short *)epio_lgcl_addr_kp_reg);
++ i &= 0xF800;
++ i |= kpdval & 0x07ff;
++ *((volatile unsigned short *)epio_lgcl_addr_kp_reg) = i;
++ spin_unlock(&epio_kp_write);
++}
++
++/**
++ * nomadik_epio_read_exp_ctrl - reads exp ctrl register of CPLD
++ *
++ * Reads the 16bit value of the expansion-board-control register of CPLD on NDK10
++ */
++short nomadik_epio_read_exp_ctrl(void)
++{
++ short i = 0;
++ spin_lock(&epio_exp_ctrl_read);
++ i = *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg);
++ spin_unlock(&epio_exp_ctrl_read);
++ return (i);
++}
++
++/**
++ * nomadik_epio_write_exp_ctrl - writes exp ctrl register of CPLD
++ * @expctrlval: value to be written
++ *
++ * Writes the provided 16bit value into the expansion-board-control register
++ * of CPLD on NDK10
++ */
++void nomadik_epio_write_exp_ctrl(unsigned short expctrlval)
++{
++ spin_lock(&epio_exp_ctrl_write);
++ *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg) = expctrlval;
++ spin_unlock(&epio_exp_ctrl_write);
++}
++
++/**
++ * nomadik_epio_init - epio module init call.
++ */
++static int __init nomadik_epio_init(void)
++{
++ unsigned short i;
++
++ nmdk_dbg_ftrace();
++ epio_lgcl_addr_cob_ident_reg =
++ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x000, (unsigned long)2);
++ epio_lgcl_addr_cob_ctl_reg =
++ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x002, (unsigned long)2);
++ epio_lgcl_addr_kp_reg =
++ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x004, (unsigned long)2);
++ epio_lgcl_addr_exp_ctrl_reg =
++ (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x006, (unsigned long)2);
++
++ i = nomadik_epio_read_cob_ident();
++ nmdk_info("Core Board Revision %d.%d, CPLD Code Revision %d.%d",
++ (i & COB_REV_BITS) >> COB_REV_BITS_POS,
++ (i & COB_REV_SUBBITS) >> COB_REV_SUBBITS_POS,
++ (i & CPLD_REV_BITS) >> CPLD_REV_BITS_POS,
++ (i & CPLD_REV_SUBBITS));
++ return 0;
++}
++#undef NMDK_DEBUG /*epio*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++/*
++ * board init
++ */
+#define BOARD_NAME CONFIG_NOMADIK_PLATFORM
+#ifndef BOARD_DEBUG
+#define BOARD_DEBUG 0
+#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
+}
+
+/*
+ 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;
+ 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;
+ 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;
+ 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[] = {
+#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
+
+/* 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)) =
+ 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;
+}
+
+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)",
+ .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 };
+
+ .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,
+ {.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)",
+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),
+};
+ [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,
+ },
+
+#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),
+
+/**
+ * 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;
+}
+
+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);
+}
+
+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);
+}
+
+/**
+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*/
+};
+
+ .resource = touchp_resources,
+};
+
++/*
++ ***********************************************************************
++ */
+#define KEYPAD_NAME "KEYPAD"
++
+#ifndef KEYPAD_DEBUG
+#define KEYPAD_DEBUG 0
+#endif
+#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
+};
+
+/**
+ /*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);
+ 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++) {
+ 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) {
+ 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,
+ 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);
+}
+
+ */
+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;
+}
+
+/**
+ */
+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;
+}
+
+ */
+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;
+}
+
+ * Initializes the key scan table (lookup table) as per pre-defined the scan
+ * codes to be passed to upper layer with respective key codes
+ */
-+u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
-+ {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
-+ {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
++static u8 kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
++ {KEY_DOWN, KEY_END, KEY_KPASTERISK, KEY_0, KEY_COMMA},
++ {KEY_RIGHT, KEY_F5, KEY_7, KEY_8, KEY_9},
++ {KEY_ENTER, KEY_LEFT, KEY_4, KEY_5, KEY_6},
++ {KEY_RIGHTMETA, KEY_F4, KEY_1, KEY_2, KEY_3},
++ {KEY_LEFTMETA, KEY_UP, KEY_F1, KEY_F2, KEY_F3}
++};
++
++static struct keypad_device keypad_board = {
++ .init = nomadik_kp_init_key_hardware,
++ .exit = nomadik_kp_exit_key_hardware,
++ .scan = nomadik_kp_key_scan,
++ .irqen = nomadik_kp_key_irqen,
++ .irqdis = nomadik_kp_key_irqdis,
++ .kcode_tbl = (u8 *) kpd_lookup_tbl,
++ .krow = 8,
++ .kcol = 8,
++};
++
++static struct resource keypad_resources[] = {
++ [0] = {
++ .start = IRQNO_GPIO(KEYPAD_IRQ),
++ .end = IRQNO_GPIO(KEYPAD_IRQ),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device keypad_device = {
++ .name = "nmdk-kp",
++ .id = 0,
++ .dev = {
++ .platform_data = &keypad_board,
++ },
++ .num_resources = ARRAY_SIZE(keypad_resources),
++ .resource = keypad_resources,
++};
++
++/*
++ ***********************************************************************
++ */
++static struct platform_device *nmdk_platform_devices[] __initdata = {
++ &smc91x_device,
++ &keypad_device,
++ &touchp_device,
++#ifdef CONFIG_MTD
++ &nomadik_nand_flash,
++ &nomadik_nor_flash,
++#endif
++};
++
++void add_nmdk_platform_devices(void)
++{
++ platform_add_devices(nmdk_platform_devices,
++ ARRAY_SIZE(nmdk_platform_devices));
++ nomadik_epio_init();
++ nomadik_platform_board_init();
++ nomadik_fsmc_init();
++ nomadik_pepperpot_board_init();
++ nomadik_smc91x_irq_init();
++}
++
++
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c
+@@ -0,0 +1,1001 @@
++/*
++ * linux/arch/arm/mach-nomadik/ndk15_devices.c
++ *
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
++ *
++ * NDK15B0x board specifc driver defination
++ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/amba/bus.h>
++#include <linux/spi/spi.h>
++#include <linux/amba/kmi.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/param.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/kpd.h>
++#include <asm/arch/touchp.h>
++#include <asm/arch/fsmc.h>
++#ifdef CONFIG_MTD
++#include <linux/mtd/nand.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/concat.h>
++#include <asm/arch/nandflash.h>
++#include <asm/mach/flash.h>
++#endif
++#include <asm/arch/debug.h>
++
++#define BOARD_NAME CONFIG_NOMADIK_PLATFORM
++#ifndef BOARD_DEBUG
++#define BOARD_DEBUG 0
++#endif
++
++#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++/**
++ * nomadik_clcd_board_enable - enables board specific clcd prameters
++ *
++ * Settings to enable backlight and pannel voltage regulator for NDK15
++ */
++void nomadik_clcd_enable(void *fbp)
++{
++ /* not implimented for this board */
++}
++
++/**
++ * nomadik_clcd_board_disable - disables board specific clcd prameters
++ *
++ * Settings to disable backlight and pannel voltage regulator for NDK10
++ */
++void nomadik_clcd_disable(void *fbp)
++{
++ /* not implimented for this board */
++}
++
++/*
++ * Settings to configure MMC controller for NDK10
++ */
++int nomadik_mmc_configure(struct amba_device *dev)
++{
++ int ret;
++ gpio_config mmc_pin;
++ char x = val_volt;
++
++ mmc_pin.dev_name = dev->dev.bus_id;
++ mmc_pin.mode = GPIO_MODE_SOFTWARE;
++ mmc_pin.direction = GPIO_DIR_OUTPUT;
++ mmc_pin.trig = GPIO_TRIG_DISABLE;
++ mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
++
++ ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++ if (ret) {
++ nmdk_error("Error in setting GPIO_PIN_75");
++ goto mmcconf_exit;
++ }
++ /* this enables power path from toureg to mmc */
++ ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id);
++ if (ret) {
++ nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
++ goto deallocate_pin_75;
++ }
++
++ ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
++ if (ret) {
++ nmdk_error("Error in writing value to touareg register");
++ goto deallocate_pin_75;
++ }
++
++ ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++ if (ret) {
++ nmdk_error("Error in gpio Altfunction enable");
++ goto deallocate_pin_75;
++ }
++ return ret;
++
++ deallocate_pin_75:
++ nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
++ mmcconf_exit:
++ return ret;
++
++}
++
++void nomadik_mmc_restore_default(struct amba_device *dev)
++{
++ nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++ nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
++}
++
++#ifdef CONFIG_MTD
++
++static struct resource nandflash_resources[] = {
++ [0] = {
++ .name = "cmem_address",
++ .start = NAND_B0_CMEM_ADDR,
++ .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "cmem_command",
++ .start = NAND_B0_CMEM_CMD,
++ .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .name = "cmem_data",
++ .start = NAND_B0_CMEM_DATA,
++ .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++#define NAND_STM_LP_OPTIONS \
++ (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
++
++static int nomadik_nandflash_exit(void)
++{
++ return 0;
++
++}
++static int nomadik_nandflash_init(void)
++{
++ /*
++ * FSMC initialization
++ * 0x0000001e => PCR0
++ * 0x000d0a00 => PMEM0
++ * 0x00100a00 => PATT0
++ */
++
++/* pcr0.address_low = 0;*/
++ gpio_config nmdknand_pin_config;
++ nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
++ nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
++ nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
++ nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
++ nmdknand_pin_config.dev_name = "nand";
++ /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */
++ if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config))
++ return -1;
++ if(nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name))
++ return -1;
++
++
++ /*Following Settings done for NAND flash protect off */
++ /* this was moved from board init to here */
++ /* This pin Conflicts with touchpanel TOUCHP_CS0*/
++ if(nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config))
++ return -1;
++ if(nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name))
++ return -1;
++ if(nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name ))
++ return -1;
++
++
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
++ DEFAULT_PCR0_VALUE;
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
++ DEFAULT_PMEM0_VALUE;
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
++ DEFAULT_PATT0_VALUE;
++ return 0;
++}
++
++static const unsigned char lookup_t[256] = {
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
++};
++
++int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
++ u_char * ecc)
++{
++ unsigned int sumCol = 0;
++ unsigned int datum, temp;
++ unsigned int glob_parity;
++ const int ecc_n_bytes = 512;
++ int i;
++
++ unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
++ unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
++ 0, parit32_1 = 0, parit32_2 = 0;
++ unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
++ 0, parit256_1 = 0, parit256_2 = 0;
++ unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
++ 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++
++ for (i = ecc_n_bytes - 1; i >= 0; --i) {
++ datum = data[i];
++ sumCol ^= datum;
++ temp = lookup_t[datum];
++
++ if (i & 0x01)
++ parit8_1 ^= temp;
++ if (i & 0x02)
++ parit16_1 ^= temp;
++ if (i & 0x04)
++ parit32_1 ^= temp;
++ if (i & 0x08)
++ parit64_1 ^= temp;
++ if (i & 0x10)
++ parit128_1 ^= temp;
++ if (i & 0x20)
++ parit256_1 ^= temp;
++ if (i & 0x40)
++ parit512_1 ^= temp;
++ if (i & 0x80)
++ parit1024_1 ^= temp;
++ if (i & 0x100)
++ parit2048_1 ^= temp;
++ }
++
++ glob_parity = lookup_t[sumCol];
++
++ parit1_1 =
++ ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
++ parit1_2 =
++ ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
++ parit2_1 =
++ ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++ parit2_2 =
++ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
++ parit4_1 =
++ ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++ parit4_2 =
++ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++
++ parit8_2 = glob_parity ^ parit8_1;
++ parit16_2 = glob_parity ^ parit16_1;
++ parit32_2 = glob_parity ^ parit32_1;
++ parit64_2 = glob_parity ^ parit64_1;
++ parit128_2 = glob_parity ^ parit128_1;
++ parit256_2 = glob_parity ^ parit256_1;
++ parit512_2 = glob_parity ^ parit512_1;
++ parit1024_2 = glob_parity ^ parit1024_1;
++ parit2048_2 = glob_parity ^ parit2048_1;
++
++ /* Pack bits */
++ ecc[0] =
++ ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
++ (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
++ << 1) |
++ parit8_2);
++ ecc[1] =
++ ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
++ (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
++ (parit128_1 << 1) | parit128_2);
++ ecc[2] =
++ ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
++ (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
++ << 1) |
++ parit2048_2);
++
++ return 0;
++}
++
++static struct nand_ecclayout nand_oob = {
++ .eccbytes = 12,
++ .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
++ .oobavail = MTD_NANDECC_AUTOPLACE,
++ .oobfree = {
++ { .offset = 8,
++ .length = 8,
++ },
++ { .offset = 24,
++ .length = 8,
++ },
++ { .offset = 40,
++ .length = 8,
++ },
++ { .offset = 56,
++ .length = 8,
++ },
++ },
++};
++
++static struct mtd_partition nandflash_main_partitions[] = {
++
++ {.name = "X-Loader(NAND)",
++ .offset = 0,
++ .size = 2 * 0x000020000}, /*256 Kbytes */
++ {.name = "MemInit(NAND)",
++ .offset = 2 * 0x000020000,
++ .size = 2 * 0x000020000}, /*128 KBytes */
++ {.name = "BootLoader(NAND)",
++ .offset = 4 * 0x000020000,
++ .size = 16 * 0x00020000}, /*2Mbytes */
++ {.name = "Kernel zImage(NAND)",
++ .offset = 20 * 0x000020000,
++ .size = 24 * 0x000020000}, /*3Mbytes */
++ {.name = "Root Filesystem(NAND)",
++ .offset = 44 * 0x000020000,
++ .size = 176 * 0x000020000}, /*22 Mbytes */
++ {.name = "User Filesystem(NAND)",
++ .offset = 220 * 0x000020000,
++ .size = 800 * 0x000020000}, /*100 Mbytes */
++};
++
++static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++
++static struct nand_bbt_descr bbt_desc = {
++ .options = 0,
++ .offs = 0,
++ .len = 2,
++ .pattern = scan_ff_pattern
++};
++
++static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl)
++{
++ struct nomadik_nand_info *drvdata =
++ container_of(mtd, struct nomadik_nand_info, mtd);
++
++ if (cmd == NAND_CMD_NONE)
++ return;
++
++ if (ctrl & NAND_NCE) {
++ *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
++ 0x40)) |= 0x04;
++ }
++ if (ctrl & NAND_CLE) {
++ writeb(cmd,drvdata->cmemc_va);
++ }
++ if (ctrl & NAND_ALE) {
++ writeb(cmd,drvdata->cmema_va);
++ }
++}
++
++static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
++ .parts = nandflash_main_partitions,
++ .num_parts = ARRAY_SIZE(nandflash_main_partitions),
++ .lp_options = NAND_STM_LP_OPTIONS,
++ .eccsize = 512,
++ .eccsteps = 4,
++ .badblockpos = 5,
++ .init = nomadik_nandflash_init,
++ .exit = nomadik_nandflash_exit,
++ .nand_oob = &nand_oob,
++ .bbt_desc = &bbt_desc,
++ .compute_ecc = nmdknand_compute_ecc512,
++ .hwcontrol = nmdknand_hwcontrol,
++};
++
++static struct platform_device nomadik_nand_flash = {
++ .name = "NOMADIK-NAND",
++ .id = 0,
++ .dev = {
++ .platform_data = &nomadik_nand_flash_data,
++ },
++ .num_resources = ARRAY_SIZE(nandflash_resources),
++ .resource = nandflash_resources,
++};
++
++static struct mtd_partition nmdkflash_main_partitions[] = {
++ {.name = "BootLoader(NOR)",
++ .size = 0x00040000, /*256K */
++ .offset = 0,},
++ {.name = "zImage+initrd(NOR)",
++ .size = 0x001C0000, /*1.75MB */
++ .offset = MTDPART_OFS_APPEND,},
++ {.name = "Root Filesystem(NOR)",
++ .size = 0x01200000, /*18MB */
++ .offset = MTDPART_OFS_APPEND,},
++ {.name = "User Filesystem(NOR)",
++ .size = 0x00800000, /*8MB */
++ .offset = MTDPART_OFS_APPEND,},
++ {.name = "initrd(NOR)",
++ .size = 0x00200000, /*4MB */
++ .offset = MTDPART_OFS_APPEND,}
++};
++
++static struct flash_platform_data nomadik_nor_flash_data = {
++ .name = "nomadik_nor",
++ .map_name = "cfi_probe",
++ /*.width = NMDK_FLASH_BUSWIDTH, */
++ .parts = nmdkflash_main_partitions,
++ .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
++};
++
++static struct resource norflash_resources[] = {
++ [0] = {
++ .name = "norflash-regs",
++ .start = NMDK_FLASH_BASE,
++ .end = (NMDK_FLASH_BASE + SZ_32M - 1),
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device nomadik_nor_flash = {
++ .name = "NOMADIK-NOR",
++ .id = 0,
++ .dev = {
++ .platform_data = &nomadik_nor_flash_data,
++ },
++ .num_resources = ARRAY_SIZE(norflash_resources),
++ .resource = norflash_resources,
++};
++
++#endif
++
++static struct resource smc91x_resources[] = {
++ [0] = {
++ .name = "smc91x-regs",
++ .start = (NOMADIK_ETH0_BASE + 0x300),
++ .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQNO_GPIO(SMC91111_IRQ),
++ .end = IRQNO_GPIO(SMC91111_IRQ),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device smc91x_device = {
++ .name = "smc91x",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(smc91x_resources),
++ .resource = smc91x_resources,
++};
++
++/*
++ * touchpanel
++ */
++#ifndef TOUCHP_DEBUG
++#define TOUCHP_DEBUG 0 /* default debug messages are disabled */
++#endif /* */
++
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */
++#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++/**
++ * nomadik_tp_ssp_board_init - board specific ssp data path setup
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the SSP for touchpanel operation
++ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
++ */
++int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
++{
++ nmdk_dbg_ftrace();
++ nomadik_epio_write_ssp_conf(EXP_SSP);
++ return (0);
++}
++
++/**
++ * nomadik_tp_gpio_board_init - board specific gpio initialization
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the GPIO for touchpanel operation
++ * RETURN: GPIO nmdk_error code
++ * SSP is interfaced with ADS7843 through CPLD hence respective
++ * interface need to be enabled for NDK10
++ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
++ * chip select, this bit allows the selection between the two
++ * peripherals. setting this bit Touch screen selected
++ */
++gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
++{
++ gpio_error status = GPIO_OK;
++ gpio_config config_cspin;
++ gpio_data touchp_cs1;
++ nmdk_dbg_ftrace();
++
++ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
++
++ /* Set SPICSn_TCHSCR pin configuration */
++ config_cspin.mode = GPIO_MODE_SOFTWARE;
++ config_cspin.direction = GPIO_DIR_OUTPUT;
++ config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
++ config_cspin.dev_name = "Touchp";
++ /*
++ * TOUCHP_CS1 need to be high always to select ad7843 cs properly
++ * this pin will be set high by nand_init(NAND_PROT_OFF)
++ * if this pin is not high and set it high
++ */
++ status |= nomadik_gpio_readpin(TOUCHP_CS1, &touchp_cs1);
++ if (!touchp_cs1) {
++ status |= nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
++ status |= nomadik_gpio_writepin(TOUCHP_CS1, 1, config_cspin.dev_name);
++ status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, config_cspin.dev_name);
++ }
++ status |= nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
++ if (status) {
++ nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
++ TOUCHP_CS0, status);
++ return (status);
++ }
++ /* Set PENIRQ pin configuration */
++ set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING);
++ return status;
++}
++
++/**
++ * nomadik_tp_gpio_board_exit - board specific gpio exit
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine performs revers action of init
++ */
++gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
++{
++ gpio_error status = GPIO_OK;
++
++ nmdk_dbg_ftrace();
++ /* Enable CPLD logic for access/interrupts on ndk15 in case of int mode */
++ if (!p_adsContext->mode) {
++ nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
++ (u16)~TSIT_MSK);
++ }
++ status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
++ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
++ return status;
++}
++
++/**
++ * nomadik_tp_pen_down - returns pen touch status
++ */
++t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
++{
++ gpio_data pen_down;
++ nmdk_dbg_ftrace();
++ pen_down = nomadik_epio_read_aux_gpi1();
++ pen_down &= TCHSCR_PENIRQ;
++ nmdk_dbg2("pen_down = 0x%d", pen_down);
++ return ((t_bool) pen_down);
++}
++
++/**
++ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
++{
++ nmdk_dbg_ftrace();
++ nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | TSIT_MSK);
++}
++
++/**
++ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
++{
++ nmdk_dbg_ftrace();
++ nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
++ (unsigned short)(~TSIT_MSK));
++}
++
++/**
++ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to disable chip select
++ */
++void nomadik_tp_spi_cs_disable(void)
++{
++ nmdk_dbg_ftrace();
++ nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
++}
++
++/**
++ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to enable chip select
++ */
++void nomadik_tp_spi_cs_enable(void)
++{
++ nmdk_dbg_ftrace();
++ nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
++}
++
++static struct touchp_device touchp_board = {
++ .ssp_init = nomadik_tp_ssp_board_init,
++ .gpio_init = nomadik_tp_gpio_board_init,
++ .gpio_exit = nomadik_tp_gpio_board_exit,
++ .pdown = nomadik_tp_pen_down,
++ .pirq_en = nomadik_tp_pen_down_irq_enable,
++ .pirq_dis = nomadik_tp_pen_down_irq_disable,
++ .cs_en = nomadik_tp_spi_cs_disable,
++ .cs_dis = nomadik_tp_spi_cs_enable,
++ .samples = 20, /*samples per second*/
++ .pollsamples = 10, /*polling per second*/
++};
++
++static struct resource touchp_resources[] = {
++ [0] = {
++ .start = IRQNO_GPIO(TOUCHP_IRQ),
++ .end = IRQNO_GPIO(TOUCHP_IRQ),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device touchp_device = {
++ .name = "nmdk-tp",
++ .id = 0,
++ .dev = {
++ .platform_data = &touchp_board,
++ },
++ .num_resources = ARRAY_SIZE(touchp_resources),
++ .resource = touchp_resources,
++};
++
++#define KEYPAD_NAME "KEYPAD"
++#ifndef KEYPAD_DEBUG
++#define KEYPAD_DEBUG 0
++#endif
++
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++/*key scan constants*/
++#define KSCAN_ALLROWS 0x00FF
++#define KSCAN_ALLCOLS 0xFF00
++#define KSCAN_ROW0 0x0001
++#define KSCAN_ROW1 0x0002
++#define KSCAN_ROW2 0x0004
++#define KSCAN_ROW3 0x0008
++#define KSCAN_ROW4 0x0010
++#define KSCAN_ROW5 0x0020
++#define KSCAN_ROW6 0x0040
++#define KSCAN_ROW7 0x0080
++#define KSCAN_COL0 0x0100
++#define KSCAN_COL1 0x0200
++#define KSCAN_COL2 0x0400
++#define KSCAN_COL3 0x0800
++#define KSCAN_COL4 0x1000
++#define KSCAN_COL5 0x2000
++#define KSCAN_COL6 0x4000
++#define KSCAN_COL7 0x8000
++
++unsigned short const keychkval_set[] = {
++ (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++};
++
++unsigned short const keychkval_read[] = {
++ KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
++ KSCAN_ROW6, KSCAN_ROW7,
++};
++
++/**
++ * nomadik_kp_ghostkey_detect - ghost key detect function
++ * @rowval: row in which ghost key to be detected
++ *
++ * when more than one key is pressed in the same row the keypad logic cannot
++ * detect proper key press, the logic here detects multiple keypress on a
++ * single row and returns error
++ */
++int nomadik_kp_ghostkey_detect(short rowval)
++{
++ int row;
++ int ghcnt = 0;
++
++ for (row = 0; row < MAX_KPROW; row++) {
++ if (0 == (rowval & keychkval_read[row])) {
++ /*keypr detected */
++ ghcnt++;
++ }
++ if (1 < ghcnt)
++ /*return error if more than one keys are pressed in a row */
++ return (-1);
++ }
++ return (0);
++}
++
++/**
++ * nomadik_kp_key_scan - keypad scan and report event function
++ *
++ * Scans through keypad hardware and updates the key status for key press
++ * or key release event to upper layer
++ */
++int nomadik_kp_key_scan(struct keypad_t *kp)
++{
++ short val;
++ u8 row, col;
++ int keyp_cnt = 0;
++ u8 *p_kcode;
++
++ nmdk_dbg_ftrace();
++ for (col = 0; col < MAX_KPCOL; col++) {
++ p_kcode = kp->board->kcode_tbl + col;
++ nomadik_epio_write_keypad(keychkval_set[col]);
++ val = nomadik_epio_read_keypad();
++ val &= KSCAN_ALLROWS;
++ if (0 == nomadik_kp_ghostkey_detect(val)) {
++ for (row = 0; row < MAX_KPROW; row++) {
++ if (0 == (val & keychkval_read[row])) { /*keypr detected */
++ keyp_cnt++;
++ if (kp->key_state[row][col] ==
++ KEYPAD_STATE_DEFAULT) {
++ input_report_key(kp->inp_dev,
++ *p_kcode, 1);
++ nmdk_dbg("P:%d ", *p_kcode);
++ kp->key_state[row][col] =
++ KEYPAD_STATE_PRESSACK;
++ }
++ } else { /*key not pressed detected */
++ if (kp->key_state[row][col] ==
++ KEYPAD_STATE_PRESSACK) {
++ input_report_key(kp->inp_dev,
++ *p_kcode, 0);
++ nmdk_dbg("R:%d ", *p_kcode);
++ kp->key_state[row][col] =
++ KEYPAD_STATE_DEFAULT;
++ }
++ }
++ p_kcode += MAX_KPROW;
++ }
++ } else
++ keyp_cnt += 0x100; /* to flag ghost keypress detection */
++ }
++ /* pull down all rows to detect any keypress */
++ nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
++ return (keyp_cnt);
++}
++
++/**
++ * nomadik_kp_init_key_hardware - keypad hardware initialization
++ *
++ * Initializes the keypad hardware specific parameters.
++ * This function will be called by nomadik_keypad_init function during init
++ * Initialize keypad interrupt handler for interrupt mode operation if enabled
++ * Initialize Keyscan matrix
++ ****************************************************************************
++ */
++int nomadik_kp_init_key_hardware(struct keypad_t *kp)
++{
++ nmdk_dbg_ftrace();
++ nomadik_epio_write_keypad(KSCAN_ALLCOLS);
++ if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
++ /*check wrong key */
++ nmdk_error("Keypad H/w error....");
++ return (-1);
++ }
++ if (!kp->mode) { /* true if interrupt mode operation */
++ /* pull down all rows to detect any keypress */
++ nomadik_epio_write_keypad(0x00);
++ /* enable keypad interrupt through CPLD logic */
++ nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() |
++ KEYP_MSK);
++ set_irq_type(kp->irq, SA_TRIGGER_RISING);
++ /*
++ * TBD logic should be added to detect proper switch settings
++ * on a board to detect valid interrupt
++ */
++ }
++ return 0;
++}
++
++/**
++ * nomadik_kp_exit_key_hardware- keypad hardware exit function
++ *
++ * This function will be called by nomadik_keypad_exit function during module
++ * exit, frees keypad interrupt if enabled
++ */
++int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
++{
++ nmdk_dbg_ftrace();
++ return 0;
++}
++
++/**
++ * nomadik_kp_key_irqen- enables keypad interrupt
++ *
++ * enables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqen(struct keypad_t *kp)
++{
++ nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | KEYP_MSK);
++ return 0;
++}
++
++/**
++ * nomadik_kp_key_irqdis- disables keypad interrupt
++ *
++ * disables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqdis(struct keypad_t *kp)
++{
++ nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
++ (unsigned short)(~KEYP_MSK));
++ return 0;
++}
++
++/*
++ * Initializes the key scan table (lookup table) as per pre-defined the scan
++ * codes to be passed to upper layer with respective key codes
++ */
++u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
++ {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
++ {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
+ {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT,
+ KEY_HOME},
+ {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U},
+ .resource = fsmc_resources,
+};
+
-+#ifdef CONFIG_CPLD_I2C
++#ifdef CONFIG_CPLD_I2C
+static void nomadik_smc91x_irq_init(void)
+{
+ nmdk_dbg_ftrace();
+
+static struct platform_device *nmdk_platform_devices[] __initdata = {
+ &fsmc_device,
-+#ifdef CONFIG_CPLD_I2C
++#ifdef CONFIG_CPLD_I2C
+ &epio_device,
+#endif
+ &keypad_device,
+ 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
+
+
+#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
+ 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
+
+
+#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
+ 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
+
+
+#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
+ 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
+
+
+#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
+ 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
+ *
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
-+ * NHK15 board specifc driver definition
++ * NDK15C02 board specifc driver defination
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/mach/flash.h>
+#endif
+#include <asm/arch/debug.h>
-+#include <asm/arch/pexp.h>
-+#include <asm/arch/touchp2003.h>
-+
-+#define DEBUG_KP(x) printk x
-+#define DEBUG_TS(x) printk x
+
+#define BOARD_NAME CONFIG_NOMADIK_PLATFORM
+#ifndef BOARD_DEBUG
+#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
+ *
+ /* 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)
+{
+ *((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 */
+};
+
+#ifdef CONFIG_MTD
-+#ifdef CONFIG_MTD_NAND
+static struct resource nandflash_resources[] = {
+ [0] = {
+ .name = "cmem_address",
+ },
+};
+
-+/*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)
+{
+}
+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;
+}
+
+}
+
+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)",
+ .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,
+ .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[] = {
+};
+#endif
+
-+#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++/*
++ * touchpanel
++ */
++#ifdef CONFIG_TOUCHSCREEN_NOMADIK
++#ifndef TOUCHP_DEBUG
++#define TOUCHP_DEBUG 0 /* default debug messages are disabled */
++#endif /* */
+
-+#ifdef CONFIG_STMPE_NOMADIK
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */
++#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
+
-+/*initialize the pins which are connected thro stmpe devices
-+ *This is not stmpe platform init function - FIXME
++/**
++ * nomadik_tp_ssp_board_init - board specific ssp data path setup
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the SSP for touchpanel operation
++ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
+ */
-+static int nomadik_stmpe_plat_init(void)
++int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
+{
-+ int err,ret;
-+
-+ /* Access the STMPE2401, and make the signal EXP1_GPIO8 as high
-+ * for NAND flash write protet off
-+ */
-+ err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_8,STMPE2401_PRIMARY_FUNCTION);
-+ if (err != STMPE2401_OK)
-+ nmdk_error("Couldn't set STMPE1 %d as primary function\n",EGPIO_PIN_8);
-+ err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_8,STMPE2401_GPIO_OUT);
-+ if (err != STMPE2401_OK)
-+ nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_8);
-+ err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_8, 1);
-+ if (err != STMPE2401_OK)
-+ nmdk_error("Couldn't set STMPE GPIO8\n");
-+
-+ /*reset the WVGA display which is conected thro port expander 1*/
-+ err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION);
-+ if (err != STMPE2401_OK)
-+ nmdk_error("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_5);
-+ err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT );
-+ if (err != STMPE2401_OK)
-+ nmdk_error("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_5);
-+ err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1);
-+ if (err != STMPE2401_OK)
-+ nmdk_error("Couldn't set STMPE GPIO5\n");
-+
-+#ifdef CONFIG_SMC91X
-+ nomadik_smc91x_irq_init();
-+ udelay(1000); /*1ms*/
-+#endif
-+ nomadik_st2590_init();
-+
-+ return 0;
++ nmdk_dbg_ftrace();
++ nomadik_epio_write_ssp_conf(EXP_SSP);
++ return (0);
+}
+
-+/*not yet implemented*/
-+int nomadik_stmpe_plat_exit(void)
++/**
++ * nomadik_tp_gpio_board_init - board specific gpio initialization
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the GPIO for touchpanel operation
++ * RETURN: GPIO nmdk_error code
++ * SSP is interfaced with ADS7843 through CPLD hence respective
++ * interface need to be enabled for NDK10
++ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
++ * chip select, this bit allows the selection between the two
++ * peripherals. setting this bit Touch screen selected
++ */
++gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
+{
-+ return 0;
-+}
++ gpio_error status = GPIO_OK;
+
-+static struct resource stmpe_resources[] = {
-+ [0] = {
-+ .name = "STMPE",
-+ .start = IRQNO_GPIO(76),
-+ .end = IRQNO_GPIO(76),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+ [1] = {
-+ .name = "STMPE",
-+ .start = IRQNO_GPIO(78),
-+ .end = IRQNO_GPIO(78),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+static struct resource nomadik_udc_resources[] = {
-+ [0] = {
-+ .name = "udc-mem",
-+ .start = IO_ADDRESS(NOMADIK_USB_BASE),
-+ .end = (IO_ADDRESS(NOMADIK_USB_BASE) + SZ_1M -1),
-+ .flags = IORESOURCE_MEM,
-+ },
++ nmdk_dbg_ftrace();
++ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
+
-+ [1] = {
-+ .name = "udc-irq",
-+ .start = INT_USBOTG,
-+ .end = INT_USBOTG,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+static struct platform_device nomadik_udc_device = {
-+ .name = "NOMADIK USBDEV",
-+ .id = 0,
-+ .num_resources = ARRAY_SIZE(nomadik_udc_resources),
-+ .resource = nomadik_udc_resources,
-+};
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++ {
++ gpio_config config_cspin;
++ /* Set SPICSn_TCHSCR pin configuration */
++ config_cspin.mode = GPIO_MODE_SOFTWARE;
++ config_cspin.direction = GPIO_DIR_OUTPUT;
++ config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
++ config_cspin.dev_name = "Touchp";
++ status = nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
++ if (status) {
++ nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
++ TOUCHP_CS0, status);
++ goto err_TOUCHP_CS0;
++ }
+
-+static struct nomadik_stmpe_platform_data nomadik_stmpe_data = {
-+ .init = nomadik_stmpe_plat_init,
-+ .exit = nomadik_stmpe_plat_exit,
-+};
++ status = nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
++ if (status) {
++ nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
++ TOUCHP_CS1, status);
++ goto err_TOUCHP_CS1;
++ }
++ }
++#endif
++ /* Set PENIRQ pin configuration */
++ set_irq_type(p_adsContext->irq, SA_TRIGGER_FALLING);
+
-+static struct platform_device nomadik_stmpe_device = {
-+ .name = "NOMADIK-STMPE",
-+ .id = 0,
-+ .dev = {
-+ .platform_data = &nomadik_stmpe_data,
-+ },
-+ .num_resources = ARRAY_SIZE(stmpe_resources),
-+ .resource = stmpe_resources,
-+};
++ return status;
+
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++ err_TOUCHP_CS1:
++ nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
++ err_TOUCHP_CS0:
++ return status;
+#endif
++}
+
-+#undef NMDK_DEBUG /*board*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+
-+/*
-+ * touchpanel
++/**
++ * nomadik_tp_gpio_board_exit - board specific gpio exit
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine performs revers action of init
+ */
-+
-+static int nomadik_tsc2003_init_irq (void (*callback)(void* parameter), void * p)
++gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
+{
-+ t_STMPE2401_error err;
-+ DEBUG_TS(("nomadik_tsc2003_init_irq\n"));
-+ err = STMPE2401_SetGpioAltFunction( STMPE1 , EGPIO_PIN_6 , STMPE2401_PRIMARY_FUNCTION );
-+ err |= STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_6,STMPE2401_GPIO_IN );
-+ err |= STMPE2401_SetGpioPull(STMPE1,EGPIO_PIN_6,STMPE2401_FLOATING );
-+
-+ err = STMPE2401_Install_Callback(STMPE1, STMPE2401_GPIO_IRQ(6), callback,(void*)p);
-+ if (err != STMPE2401_OK) {
-+ printk("Couldn't setup touch screen callback\n");
-+ }
-+ err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_FALL_EDGE);
-+ if (err != STMPE2401_OK) {
-+ printk("Couldn't set touch screen edge detection\n");
-+ }
-+ err = STMPE2401_ClearGpioEdgeStatus(STMPE1,(0x1<<EGPIO_PIN_6));
-+ if (err != STMPE2401_OK) {
-+ printk("Couldn't clear touch screen edge status \n");
-+ }
-+ /*err = STMPE2401_InterruptAbilitation(STMPE1, STMPE2401_ENABLE_INTERRUPT );
-+ if (err != STMPE2401_OK) {
-+ printk("Couldn't enable touch screen callback\n");
-+ }*/
-+ return (err != STMPE2401_OK);
++ gpio_error status = GPIO_OK;
++
++ nmdk_dbg_ftrace();
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++ status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
++ status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
++#endif
++ nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
++ return status;
+}
+
-+static int nomadik_tsc2003_exit_irq(void)
++/**
++ * nomadik_tp_pen_down - returns pen touch status
++ */
++t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
+{
-+ t_STMPE2401_error err;
-+ DEBUG_TS(("nomadik_tsc2003_exit_irq\n"));
-+ err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
-+ err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_NO_EDGE);
-+ return (err != STMPE2401_OK);
++ gpio_data pen_down;
++
++ nmdk_dbg_ftrace();
++ nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
++ nmdk_dbg2("pen_down = 0x%d (pin%d)",
++ pen_down, GPIO_PIN_FOR_IRQ(p_adsContext->irq));
++ return ((t_bool) pen_down);
+}
+
-+static int nomadik_tsc2003_irqen(void)
++/**
++ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
+{
-+ t_STMPE2401_error err;
-+ //DEBUG_TS(("nomadik_tsc2003_irqen\n"));
-+ err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_ENABLE_INTERRUPT );
-+ return (err != STMPE2401_OK);
++ nmdk_dbg_ftrace();
++ enable_irq(p_adsContext->irq);
+}
+
-+static int nomadik_tsc2003_irqdis(void)
++/**
++ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
+{
-+ t_STMPE2401_error err;
-+ //DEBUG_TS(("nomadik_tsc2003_irqdis\n"));
-+ err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
-+ return (err != STMPE2401_OK);
++ nmdk_dbg_ftrace();
++ disable_irq(p_adsContext->irq);
+}
+
-+static int nomadik_tsc2003_irq_ack(void)
++/**
++ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to disable chip select
++ */
++void nomadik_tp_spi_cs_disable(void)
+{
-+ u16 irqSource = 0x100;
-+ u32 irqGpioSource = 0x40;
-+ t_STMPE2401_error err;
-+ //DEBUG_TS(("nomadik_tsc2003_irq_ack\n"));
-+ err = STMPE2401_Acknowledge(STMPE1,irqSource,irqGpioSource);
-+ return (err != STMPE2401_OK);
++ nmdk_dbg_ftrace();
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++ nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
++ nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
++#endif
+}
+
-+static int nomadik_tsc2003_read_pin_val(u8 * Value)
++/**
++ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to enable chip select
++ */
++void nomadik_tp_spi_cs_enable(void)
+{
-+ t_STMPE2401_error err;
-+
-+ err = STMPE2401_GetGpioVal(STMPE1 , EGPIO_PIN_6, Value);
-+ return (err != STMPE2401_OK);
++ nmdk_dbg_ftrace();
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++ nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
++ nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
++#endif
+}
-+static struct touchp_tsc2003_device touchp_tsc2003_board = {
-+ .irq_init = nomadik_tsc2003_init_irq,
-+ .irq_exit = nomadik_tsc2003_exit_irq,
-+ .pirq_en = nomadik_tsc2003_irqen,
-+ .pirq_dis = nomadik_tsc2003_irqdis,
-+ .pirq_ack = nomadik_tsc2003_irq_ack,
-+ .pirq_read_val = nomadik_tsc2003_read_pin_val,
++
++static struct touchp_device touchp_board = {
++ .ssp_init = nomadik_tp_ssp_board_init,
++ .gpio_init = nomadik_tp_gpio_board_init,
++ .gpio_exit = nomadik_tp_gpio_board_exit,
++ .pdown = nomadik_tp_pen_down,
++ .pirq_en = nomadik_tp_pen_down_irq_enable,
++ .pirq_dis = nomadik_tp_pen_down_irq_disable,
++ .cs_en = nomadik_tp_spi_cs_disable,
++ .cs_dis = nomadik_tp_spi_cs_enable,
++ .samples = 100, /*samples per second*/
++ .pollsamples = 10, /*polling per second*/
+};
+
-+static struct platform_device touchp_tsc2003_device = {
-+ //.name = "nmdk-tp",
-+ .name = "tsc2003",
++static struct resource touchp_resources[] = {
++ [0] = {
++ .start = IRQNO_GPIO(TOUCHP_IRQ),
++ .end = IRQNO_GPIO(TOUCHP_IRQ),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device touchp_device = {
++ .name = "nmdk-tp",
+ .id = 0,
+ .dev = {
-+ .platform_data = &touchp_tsc2003_board,
++ .platform_data = &touchp_board,
+ },
-+ .num_resources = 0,
-+ .resource = NULL,
++ .num_resources = ARRAY_SIZE(touchp_resources),
++ .resource = touchp_resources,
+};
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#endif
+
-+/*
-+ * keypad
-+ */
++#ifdef CONFIG_KEYPAD_NOMADIK
++#define KEYPAD_NAME "KEYPAD"
++#ifndef KEYPAD_DEBUG
++#define KEYPAD_DEBUG 0
++#endif
+
-+#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
+
-+static void kp_callback (void * parameter)
++/*key scan constants*/
++#define KSCAN_ALLROWS 0x00FF
++#define KSCAN_ALLCOLS 0xFF00
++#define KSCAN_ROW0 0x0001
++#define KSCAN_ROW1 0x0002
++#define KSCAN_ROW2 0x0004
++#define KSCAN_ROW3 0x0008
++#define KSCAN_ROW4 0x0010
++#define KSCAN_ROW5 0x0020
++#define KSCAN_ROW6 0x0040
++#define KSCAN_ROW7 0x0080
++#define KSCAN_COL0 0x0100
++#define KSCAN_COL1 0x0200
++#define KSCAN_COL2 0x0400
++#define KSCAN_COL3 0x0800
++#define KSCAN_COL4 0x1000
++#define KSCAN_COL5 0x2000
++#define KSCAN_COL6 0x4000
++#define KSCAN_COL7 0x8000
++
++unsigned short const keychkval_set[] = {
++ (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
++ (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++};
++
++unsigned short const keychkval_read[] = {
++ KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
++ KSCAN_ROW6, KSCAN_ROW7,
++};
++
++/**
++ * nomadik_kp_ghostkey_detect - ghost key detect function
++ * @rowval: row in which ghost key to be detected
++ *
++ * when more than one key is pressed in the same row the keypad logic cannot
++ * detect proper key press, the logic here detects multiple keypress on a
++ * single row and returns error
++ */
++int nomadik_kp_ghostkey_detect(short rowval)
+{
-+ t_STMPE2401_error err;
-+ t_STMPE2401_key_status keys;
-+ struct keypad_t * kp = (struct keypad_t *)parameter;
-+ u8 kcode,i;
++ int row;
++ int ghcnt = 0;
+
-+ /*DEBUG_KP(("kp_callback\n"));*/
-+ err = STMPE2401_Keypressed(STMPE0, &keys);
-+ if(keys.buttonPressed)
-+ {
-+ for(i=0;i<keys.buttonPressed;i++)
-+ {
-+ kcode = kp->board->kcode_tbl[(keys.button[i]&0x3)*4 + ((keys.button[i]>>3)&0x3)];
-+ input_report_key(kp->inp_dev,kcode, 1);
-+ }
-+ }
-+ if(keys.buttonReleased)
-+ {
-+ for(i=0;i<keys.buttonReleased;i++)
-+ {
-+ kcode = kp->board->kcode_tbl[(keys.released[i]&0x3)*4 + ((keys.released[i]>>3)&0x3)];
-+ input_report_key(kp->inp_dev,kcode, 0);
-+ }
-+ }
++ for (row = 0; row < MAX_KPROW; row++) {
++ if (0 == (rowval & keychkval_read[row])) {
++ /*keypr detected */
++ ghcnt++;
++ }
++ if (1 < ghcnt)
++ /*return error if more than one keys are pressed in a row */
++ return (-1);
++ }
++ return (0);
+}
+
+/**
-+ * nomadik_kp_init_key_hardware - keypad hardware initialization
++ * nomadik_kp_key_scan - keypad scan and report event function
+ *
-+ ****************************************************************************
++ * Scans through keypad hardware and updates the key status for key press
++ * or key release event to upper layer
+ */
-+int nomadik_kp_init_key_hardware(struct keypad_t *kp)
++int nomadik_kp_key_scan(struct keypad_t *kp)
+{
-+ t_STMPE2401_error err;
-+ t_STMPE2401_key_config kpconfig;
++ short val;
++ u8 row, col;
++ int keyp_cnt = 0;
++ u8 *p_kcode;
+
-+ DEBUG_KP(("nomadik_kp_init_key_hardware\n"));
+ nmdk_dbg_ftrace();
-+ /*setup Columns GPIOs (inputs)*/
-+ kpconfig.columns = 0xF; //4 columns
-+ kpconfig.rows = 0xF; //4 rows
-+ kpconfig.nCycles = 8; //number of cycles for key data updating
-+ kpconfig.debounce = 64; //de-bounce time 64 ms
-+ kpconfig.scan = STMPE2401_SCAN_OFF;
-+ err = STMPE2401_Keypad_init(STMPE0, kpconfig);
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't setup keypad configuration\n");
-+ }
-+ if (!kp->mode)
-+ { /* true if interrupt mode operation */
-+ DEBUG_KP(("\tsetting up keypad interrupt stuff\n"));
-+ err = STMPE2401_Install_Callback(STMPE0, STMPE2401_KEYPAD_IRQ,kp_callback,(void*)kp);
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't setup keypad callback\n");
-+ }
-+ err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't abilitate the keypad source interrupt\n");
-+ }
-+ /*err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_ENABLE_INTERRUPT );
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't enable the keypad source interrupt\n");
-+ }*/
-+ }
-+ err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_ON);
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't enable keypad scan\n");
++ for (col = 0; col < MAX_KPCOL; col++) {
++ p_kcode = kp->board->kcode_tbl + col;
++ nomadik_epio_write_keypad(keychkval_set[col]);
++ val = nomadik_epio_read_keypad();
++ val &= KSCAN_ALLROWS;
++ if (0 == nomadik_kp_ghostkey_detect(val)) {
++ for (row = 0; row < MAX_KPROW; row++) {
++ if (0 == (val & keychkval_read[row])) { /*keypr detected */
++ keyp_cnt++;
++ if (kp->key_state[row][col] ==
++ KEYPAD_STATE_DEFAULT) {
++ input_report_key(kp->inp_dev,
++ *p_kcode, 1);
++ nmdk_dbg("P:%d ", *p_kcode);
++ kp->key_state[row][col] =
++ KEYPAD_STATE_PRESSACK;
++ }
++ } else { /*key not pressed detected */
++ if (kp->key_state[row][col] ==
++ KEYPAD_STATE_PRESSACK) {
++ input_report_key(kp->inp_dev,
++ *p_kcode, 0);
++ nmdk_dbg("R:%d ", *p_kcode);
++ kp->key_state[row][col] =
++ KEYPAD_STATE_DEFAULT;
++ }
++ }
++ p_kcode += MAX_KPROW;
++ }
++ } else
++ keyp_cnt += 0x100; /* to flag ghost keypress detection */
+ }
-+ return 0;
++ /* pull down all rows to detect any keypress */
++ nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
++ return (keyp_cnt);
+}
+
+/**
-+ * nomadik_kp_exit_key_hardware- keypad hardware exit function
++ * nomadik_kp_init_key_hardware - keypad hardware initialization
+ *
++ * Initializes the keypad hardware specific parameters.
++ * This function will be called by nomadik_keypad_init function during init
++ * Initialize keypad interrupt handler for interrupt mode operation if enabled
++ * Initialize Keyscan matrix
++ ****************************************************************************
+ */
-+int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
++int nomadik_kp_init_key_hardware(struct keypad_t *kp)
+{
-+ t_STMPE2401_error err;
-+
-+ DEBUG_KP(("nomadik_kp_exit_key_hardware\n"));
-+ err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_OFF);
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't enable keypad scan\n");
-+ }
-+ if (!kp->mode)
-+ { /* true if interrupt mode operation */
-+ err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_DISABLE_INTERRUPT );
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't disable keypad callback\n");
-+ }
-+ err = STMPE2401_Remove_Callback(STMPE0, STMPE2401_KEYPAD_IRQ);
-+ if (err != STMPE2401_OK)
-+ {
-+ printk("Couldn't remove keypad callback\n");
-+ }
-+ }
+ nmdk_dbg_ftrace();
++ nomadik_epio_write_keypad(KSCAN_ALLCOLS);
++ if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
++ /*check wrong key */
++ nmdk_error("Keypad H/w error....");
++ return (-1);
++ }
++ if (!kp->mode) { /* true if interrupt mode operation */
++ /* pull down all rows to detect any keypress */
++ nomadik_epio_write_keypad(KSCAN_ALLROWS);
++ set_irq_type(kp->irq, SA_TRIGGER_FALLING);
++ /*
++ * TBD logic should be added to detect proper switch settings
++ * on a board to detect valid interrupt
++ */
++ }
+ return 0;
+}
+
+/**
-+ * nomadik_kp_key_scan - keypad scan and report event function
++ * nomadik_kp_exit_key_hardware- keypad hardware exit function
+ *
++ * This function will be called by nomadik_keypad_exit function during module
++ * exit, frees keypad interrupt if enabled
+ */
-+int nomadik_kp_key_scan(struct keypad_t *kp)
++int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
+{
-+ DEBUG_KP(("nomadik_kp_key_scan\n"));
-+ kp_callback ((void *) kp);
++ nmdk_dbg_ftrace();
++ /* pull up all columns so that interrupt will not be raised*/
++ nomadik_epio_write_keypad(KSCAN_ALLCOLS |KSCAN_ALLCOLS);
+ return 0;
+}
+
+ */
+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;
+}
+
+/**
+ */
+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 = {
+ .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",
+ .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)
+ 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
+
+
+#target name configuration for this target
+config NOMADIK_TARGET
-+ string
++ string
+ default NHK15
+
+# nomadik soc chip name configuration for this target
+ default y
+
+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arch/arm/mach-nomadik/normal.S
---- linux-2.6.20/arch/arm/mach-nomadik/normal.S 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/normal.S 2008-07-28 15:20:42.000000000 +0530
-@@ -0,0 +1,199 @@
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c
+@@ -0,0 +1,1009 @@
+/*
-+ * arch/arm/mach-nomadik/normal.S
++ * linux/arch/arm/mach-nomadik/nhk15_devices.c
+ *
-+ * Copyright 2007, STMicroelectronics
++ * Copyright (C) STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
+ *
++ * NHK15 board specifc driver definition
+ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/amba/bus.h>
++#include <linux/spi/spi.h>
++#include <linux/amba/kmi.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/param.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/kpd.h>
++#include <asm/arch/touchp.h>
++#include <asm/arch/fsmc.h>
++#ifdef CONFIG_MTD
++#include <linux/mtd/nand.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/concat.h>
++#include <asm/arch/nandflash.h>
++#include <asm/mach/flash.h>
++#endif
++#include <asm/arch/debug.h>
++#include <asm/arch/pexp.h>
++#include <asm/arch/touchp2003.h>
+
-+#define NORMAL_DEBUG 0
-+#define mpmc_base 0xF0110000
-+#define src_base 0xf01e0000
-+#define pmu_base 0xf01e9000
-+#define uart_base 0xcc85e000
-+
++#define DEBUG_KP(x) printk x
++#define DEBUG_TS(x) printk x
+
++#define BOARD_NAME CONFIG_NOMADIK_PLATFORM
++#ifndef BOARD_DEBUG
++#define BOARD_DEBUG 0
++#endif
+
++#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
+
-+.align 5
-+.globl nomadik_normal_mode
++#define INT_USBOTG 23
++#define NOMADIK_USB_BASE 0x10170000
++#ifdef CONFIG_SMC91X
++static void nomadik_smc91x_irq_init(void);
++#endif
+
-+nomadik_normal_mode:
++/**
++ * nomadik_clcd_board_enable - enables board specific clcd prameters
++ *
++ * Settings to enable backlight and pannel voltage regulator for NDK15
++ */
++void nomadik_clcd_enable(void *fbp)
++{
++ /* not implimented for this board */
++}
+
++/**
++ * nomadik_clcd_board_disable - disables board specific clcd prameters
++ *
++ * Settings to disable backlight and pannel voltage regulator for NDK10
++ */
++void nomadik_clcd_disable(void *fbp)
++{
++ /* not implimented for this board */
++}
+
-+ stmfd sp!,{r0-r12,lr}
++/*
++ * Settings to configure MMC controller for NDK10
++ */
++int nomadik_mmc_configure(struct amba_device *dev)
++{
++ /* not implimented for this board */
++ int ret;
++ char x = val_volt;
++ ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
++ if (ret) {
++ nmdk_error("Error in writing value to touareg register");
+
-+ ldr r10,=mpmc_base
-+ ldr r11,=src_base
-+ ldr r12,=pmu_base
-+ ldr r9,=uart_base
++ }
+
++ ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++ if (ret) {
++ nmdk_error("Error in gpio Altfunction enable");
+
-+ ldr r2, [r11]
-+
-+#if NORMAL_DEBUG
-+ mov r0, #97
-+ str r0, [r9]
-+#endif
++ }
++ return ret;
+
-+ /* Prefetch certain instructions in the cache. */
-+ adr r4, cache_prefetch_start
-+ adr r5, cache_prefetch_end
-+ mvn r1,#0x1F
-+ ands r4,r1,r4
-+pfetch:
-+ mcr p15, 0, r4, c7, c13,1
-+ cmp r4,r5
-+ addls r4, r4, #0x20
-+ bls pfetch
++ return 0;
++}
+
-+.align 5
-+
-+cache_prefetch_start:
-+ ldr r10, =mpmc_base
++void nomadik_mmc_restore_default(struct amba_device *dev)
++{
++ /* not implimented for this board */
++ nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++}
+
-+poll_status:
-+ /* Check sdram is not busy */
-+ ldr r1,[r10, #0x4]
-+ ands r1,r1,#0x1
-+ cmp r1,#0
-+ bne poll_status
++static int fsmc_platform_init(void)
++{
++ unsigned char __iomem *fsmc_base;
+
-+ /* Put SDRAM in self-refresh mode*/
-+ ldr r1,[r10, #0x20]
-+ bic r1,r1,#0x1
-+ orr r1,r1,#0x04
-+ str r1,[r10, #0x20]
++ nmdk_dbg_ftrace();
++ /*Following Settings done for NAND flash protect off */
++ fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
+
++ /* for NOR accesss */
++ /* Initialize the fsmc bank 0 */
++ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
++ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
++ /* Initialize the fsmc bank 1 used for ethernet controller */
++ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x305B;
++ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x033F33; /*old 00000702 */
+
-+ /*Wait for SDRAM to go in self-refresh*/
-+wait_self_refresh:
-+ ldr r1,[r10,#0x4]
-+ and r1,r1,#0x4
-+ cmp r1,#0x0
-+ beq wait_self_refresh
++ *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
++ /* Above Settings done for NAND flash protect off */
++ return 0;
++}
+
-+ /**
-+ * Stop the DLL, leave SDMC on
-+ Moving 0xff9 into sdmc control register for stopping and adding dll
++static struct resource fsmc_resources[] = {
++ [0] = {
++ .start = NOMADIK_FSMC_BASE,
++ .end = NOMADIK_FSMC_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++struct fsmc_platform_data fsmc_data = {
++ .init = fsmc_platform_init,
++};
++
++static struct platform_device fsmc_device = {
++ .name = "NOMADIK-FSMC",
++ .id = 0,
++ .dev = {
++ .platform_data = &fsmc_data,
++ },
++ .num_resources = ARRAY_SIZE(fsmc_resources),
++ .resource = fsmc_resources,
++};
++
++#ifdef CONFIG_MTD
++#ifdef CONFIG_MTD_NAND
++static struct resource nandflash_resources[] = {
++ [0] = {
++ .name = "cmem_address",
++ .start = NAND_B0_CMEM_ADDR,
++ .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = "cmem_command",
++ .start = NAND_B0_CMEM_CMD,
++ .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .name = "cmem_data",
++ .start = NAND_B0_CMEM_DATA,
++ .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++/*NHK15 is 8-bit NAND*/
++#define NAND_STM_LP_OPTIONS \
++ ( NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING | NAND_NO_READRDY | NAND_NO_AUTOINCR)
++
++int nomadik_nandflash_exit(void)
++{
++ return 0;
++
++}
++int nomadik_nandflash_init(void)
++{
++#if 1
++ /*
++ * FSMC initialization
++ * 0x0000000e => PCR0
++ * 0x000d0a00 => PMEM0
++ * 0x00100a00 => PATT0
++ */
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
++ 0x0000000E; /* NHK15 is 8-bit NAND */
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
++ DEFAULT_PMEM0_VALUE;
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
++ DEFAULT_PATT0_VALUE;
++#endif
++ return 0;
++}
++
++const unsigned char lookup_t[256] = {
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
++};
++
++int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
++ u_char * ecc)
++{
++ unsigned int sumCol = 0;
++ unsigned int datum, temp;
++ unsigned int glob_parity;
++ const int ecc_n_bytes = 512;
++ int i;
++
++ unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
++ unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
++ 0, parit32_1 = 0, parit32_2 = 0;
++ unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
++ 0, parit256_1 = 0, parit256_2 = 0;
++ unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
++ 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++
++ for (i = ecc_n_bytes - 1; i >= 0; --i) {
++ datum = data[i];
++ sumCol ^= datum;
++ temp = lookup_t[datum];
++
++ if (i & 0x01)
++ parit8_1 ^= temp;
++ if (i & 0x02)
++ parit16_1 ^= temp;
++ if (i & 0x04)
++ parit32_1 ^= temp;
++ if (i & 0x08)
++ parit64_1 ^= temp;
++ if (i & 0x10)
++ parit128_1 ^= temp;
++ if (i & 0x20)
++ parit256_1 ^= temp;
++ if (i & 0x40)
++ parit512_1 ^= temp;
++ if (i & 0x80)
++ parit1024_1 ^= temp;
++ if (i & 0x100)
++ parit2048_1 ^= temp;
++ }
++
++ glob_parity = lookup_t[sumCol];
++
++ parit1_1 =
++ ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
++ parit1_2 =
++ ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
++ parit2_1 =
++ ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++ parit2_2 =
++ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
++ parit4_1 =
++ ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++ parit4_2 =
++ ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++
++ parit8_2 = glob_parity ^ parit8_1;
++ parit16_2 = glob_parity ^ parit16_1;
++ parit32_2 = glob_parity ^ parit32_1;
++ parit64_2 = glob_parity ^ parit64_1;
++ parit128_2 = glob_parity ^ parit128_1;
++ parit256_2 = glob_parity ^ parit256_1;
++ parit512_2 = glob_parity ^ parit512_1;
++ parit1024_2 = glob_parity ^ parit1024_1;
++ parit2048_2 = glob_parity ^ parit2048_1;
++
++ /* Pack bits */
++ ecc[0] =
++ ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
++ (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
++ << 1) |
++ parit8_2);
++ ecc[1] =
++ ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
++ (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
++ (parit128_1 << 1) | parit128_2);
++ ecc[2] =
++ ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
++ (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
++ << 1) |
++ parit2048_2);
++
++ return 0;
++}
++
++static struct nand_ecclayout nand_oob = {
++ .eccbytes = 12,
++ .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
++ .oobavail = MTD_NANDECC_AUTOPLACE,
++ .oobfree = {
++ { .offset = 8,
++ .length = 8,
++ },
++ { .offset = 24,
++ .length = 8,
++ },
++ { .offset = 40,
++ .length = 8,
++ },
++ { .offset = 56,
++ .length = 8,
++ },
++ },
++};
++static struct mtd_partition nandflash_main_partitions[] = {
++
++ {.name = "X-Loader(NAND)",
++ .offset = 0,
++ .size = 2 * 0x000020000}, /*256 Kbytes */
++ {.name = "MemInit(NAND)",
++ .offset = 2 * 0x000020000,
++ .size = 2 * 0x000020000}, /*128 KBytes */
++ {.name = "BootLoader(NAND)",
++ .offset = 4 * 0x000020000,
++ .size = 16 * 0x00020000}, /*2Mbytes */
++ {.name = "Kernel zImage(NAND)",
++ .offset = 20 * 0x000020000,
++ .size = 24 * 0x000020000}, /*3Mbytes */
++ {.name = "Root Filesystem(NAND)",
++ .offset = 44 * 0x000020000,
++ .size = 176 * 0x000020000}, /*22 Mbytes */
++ {.name = "User Filesystem(NAND)",
++ .offset = 220 * 0x000020000,
++ .size = 800 * 0x000020000}, /*100 Mbytes */
++};
++
++uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++
++struct nand_bbt_descr bbt_desc = {
++ .options = 0,
++ .offs = 0,
++ .len = 2,
++ .pattern = scan_ff_pattern
++};
++
++static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl)
++{
++ struct nomadik_nand_info *drvdata =
++ container_of(mtd, struct nomadik_nand_info, mtd);
++
++ if (cmd == NAND_CMD_NONE)
++ return;
++
++ if (ctrl & NAND_NCE) {
++ *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
++ 0x40)) |= 0x04;
++ }
++ if (ctrl & NAND_CLE) {
++ writeb(cmd,drvdata->cmemc_va);
++ }
++ if (ctrl & NAND_ALE) {
++ writeb(cmd,drvdata->cmema_va);
++ }
++}
++
++static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
++ .parts = nandflash_main_partitions,
++ .num_parts = ARRAY_SIZE(nandflash_main_partitions),
++ .lp_options = NAND_STM_LP_OPTIONS,
++ .eccsize = 512,
++ .eccsteps = 4,
++ /*.badblockpos = 5,*/
++ .badblockpos = 6,
++ .init = nomadik_nandflash_init,
++ .exit = nomadik_nandflash_exit,
++ .nand_oob = &nand_oob,
++ .bbt_desc = &bbt_desc,
++ .compute_ecc = nmdknand_compute_ecc512,
++ .hwcontrol = nmdknand_hwcontrol,
++};
++
++static struct platform_device nomadik_nand_flash = {
++ .name = "NOMADIK-NAND",
++ .id = 0,
++ .dev = {
++ .platform_data = &nomadik_nand_flash_data,
++ },
++ .num_resources = ARRAY_SIZE(nandflash_resources),
++ .resource = nandflash_resources,
++};
++#endif //CONFIG_MTD_NAND
++
++#ifdef CONFIG_MTD_ONENAND
++static int nomadik_1nand_init(void)
++{ int ret=0;
++ int fsmc_err=1;
++ int board=8820;
++
++ /*Set the reset signal to high*/
++ ret = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_9,STMPE2401_PRIMARY_FUNCTION);
++ if (ret != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE1 %d as primary function\n",EGPIO_PIN_9);
++ ret = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_9,STMPE2401_GPIO_OUT);
++ if (ret != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_9);
++ ret = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_9, 1);
++
++ /*Configure other GPIO pins to ALT FUNC A*/
++ ret = nomadik_gpio_altfuncenable(GPIO_ALT_ONENAND, "onenand");
++ if (ret)
++ { nmdk_error("Could not set oneNAND GPIO alternate function correctly\n");
++ printk("\n>ERROR to config GPIO %d", ret);
++ return -1;
++ }
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = DEFAULT_BCR0_VALUE;
++ *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = DEFAULT_BTR0_VALUE;
++ return 0;
++}
++
++void nomadik_1nand_exit(void)
++{ int ret=0;
++ ret=nomadik_gpio_altfuncdisable(GPIO_ALT_ONENAND, "onenand");
++ if(!ret)
++ return;
++ else
++ { printk("Could not Disable ST ONENAND GPIO alternate function \n");
++ }
++}
++
++
++
++static struct resource nomadik_1nand_resource[] = {
++ [0] = {
++ .start = NOMADIK_1NAND_BASE,
++ .end = NOMADIK_1NAND_BASE + SZ_128K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++static struct mtd_partition onenandflash_main_partitions[] = {
++ {.name = "X-Loader(ONENAND)",
++ .offset = 0,
++ .size = 2 * 0x000020000}, /*256 Kbytes */
++ {.name = "MemInit(ONENAND)",
++ .offset = 2 * 0x000020000,
++ .size = 2 * 0x000020000}, /*256 KBytes */
++ {.name = "BootLoader(ONENAND)",
++ .offset = 4 * 0x000020000,
++ .size = 16 * 0x00020000}, /*2Mbytes */
++ {.name = "Kernel zImage(ONENAND)",
++ .offset = 20 * 0x000020000,
++ .size = 32 * 0x000020000}, /*4Mbytes */
++ {.name = "Root Filesystem(ONENAND)",
++ .offset = 52 * 0x000020000,
++ .size = 176 * 0x000020000}, /*22 Mbytes */
++ {.name = "User Filesystem(ONENAND)",
++ .offset = 228 * 0x000020000,
++ .size = 1820 * 0x000020000}, /*227.5 Mbytes */
++};
++
++static struct flash_platform_data nomadik_1nand_flash_data={
++ .init=nomadik_1nand_init,
++ .exit=nomadik_1nand_exit,
++ .name="onenand",
++ .parts=onenandflash_main_partitions,
++ .nr_parts=ARRAY_SIZE(onenandflash_main_partitions),
++};
++
++static struct platform_device nomadik_1nand_flash = {
++ .name = "onenand",
++ .id = 0,
++ .dev = {
++ .bus_id = "1nand",
++ .platform_data = &nomadik_1nand_flash_data,
++ },
++ .num_resources = ARRAY_SIZE(nomadik_1nand_resource),
++ .resource = nomadik_1nand_resource,
++};
++#endif //CONFIG_MTD_ONENAND
++#endif
++
++#undef NMDK_DEBUG /*board*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++static void nomadik_st2590_init(void)
++{
++ t_STMPE2401_error err;
++
++ nomadik_gpio_altfuncenable(GPIO_ALT_UART_0_MODEM, "BT");
++ nomadik_gpio_altfuncenable(GPIO_ALT_MSP_2, "BT");
++ /*reset the bt controller which is conected thro port expander 0*/
++ err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_16,STMPE2401_PRIMARY_FUNCTION);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE%d %d as primary function\n",STMPE0,EGPIO_PIN_16);
++ }
++ err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_16,STMPE2401_GPIO_OUT );
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE0 EGPIO:%d in Output direction\n", EGPIO_PIN_16);
++ }
++ err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,0);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE0 GPIO16\n");
++ }
++ msleep(100);
++ err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,1);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE0 GPIO16\n");
++ }
++ printk("BT Reset Applied !!\n");
++}
++#ifdef CONFIG_SMC91X
++static void nomadik_smc91x_irq_init(void)
++{
++ t_STMPE2401_error err;
++
++ nomadik_gpio_altfuncenable(GPIO_ALT_ETHERNET, "ETH");
++ /*reset the ethernet controller which is conected thro port expander 1*/
++ err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_10,STMPE2401_PRIMARY_FUNCTION);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_10);
++ }
++ err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_10,STMPE2401_GPIO_OUT );
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_10);
++ }
++ err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_10,0);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't set STMPE GPIO10\n");
++ }
++ mdelay(200);
++}
++
++static struct resource smc91x_resources[] = {
++ [0] = {
++ .name = "smc91x-regs",
++ .start = (NOMADIK_ETH0_BASE + 0x300),
++ .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQNO_GPIO(SMC91111_IRQ),
++ .end = IRQNO_GPIO(SMC91111_IRQ),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device smc91x_device = {
++ .name = "smc91x",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(smc91x_resources),
++ .resource = smc91x_resources,
++};
++#endif
++
++#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++#ifdef CONFIG_STMPE_NOMADIK
++
++/*initialize the pins which are connected thro stmpe devices
++ *This is not stmpe platform init function - FIXME
++ */
++static int nomadik_stmpe_plat_init(void)
++{
++ int err,ret;
++
++ /* Access the STMPE2401, and make the signal EXP1_GPIO8 as high
++ * for NAND flash write protet off
++ */
++ err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_8,STMPE2401_PRIMARY_FUNCTION);
++ if (err != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE1 %d as primary function\n",EGPIO_PIN_8);
++ err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_8,STMPE2401_GPIO_OUT);
++ if (err != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_8);
++ err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_8, 1);
++ if (err != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE GPIO8\n");
++
++ /*reset the WVGA display which is conected thro port expander 1*/
++ err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION);
++ if (err != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_5);
++ err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT );
++ if (err != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_5);
++ err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1);
++ if (err != STMPE2401_OK)
++ nmdk_error("Couldn't set STMPE GPIO5\n");
++
++#ifdef CONFIG_SMC91X
++ nomadik_smc91x_irq_init();
++ udelay(1000); /*1ms*/
++#endif
++ nomadik_st2590_init();
++
++ return 0;
++}
++
++/*not yet implemented*/
++int nomadik_stmpe_plat_exit(void)
++{
++ return 0;
++}
++
++static struct resource stmpe_resources[] = {
++ [0] = {
++ .name = "STMPE",
++ .start = IRQNO_GPIO(76),
++ .end = IRQNO_GPIO(76),
++ .flags = IORESOURCE_IRQ,
++ },
++ [1] = {
++ .name = "STMPE",
++ .start = IRQNO_GPIO(78),
++ .end = IRQNO_GPIO(78),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++static struct resource nomadik_udc_resources[] = {
++ [0] = {
++ .name = "udc-mem",
++ .start = IO_ADDRESS(NOMADIK_USB_BASE),
++ .end = (IO_ADDRESS(NOMADIK_USB_BASE) + SZ_1M -1),
++ .flags = IORESOURCE_MEM,
++ },
++
++ [1] = {
++ .name = "udc-irq",
++ .start = INT_USBOTG,
++ .end = INT_USBOTG,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++static struct platform_device nomadik_udc_device = {
++ .name = "NOMADIK USBDEV",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(nomadik_udc_resources),
++ .resource = nomadik_udc_resources,
++};
++
++static struct nomadik_stmpe_platform_data nomadik_stmpe_data = {
++ .init = nomadik_stmpe_plat_init,
++ .exit = nomadik_stmpe_plat_exit,
++};
++
++static struct platform_device nomadik_stmpe_device = {
++ .name = "NOMADIK-STMPE",
++ .id = 0,
++ .dev = {
++ .platform_data = &nomadik_stmpe_data,
++ },
++ .num_resources = ARRAY_SIZE(stmpe_resources),
++ .resource = stmpe_resources,
++};
++
++#endif
++
++#undef NMDK_DEBUG /*board*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++/*
++ * touchpanel
++ */
++
++static int nomadik_tsc2003_init_irq (void (*callback)(void* parameter), void * p)
++{
++ t_STMPE2401_error err;
++ DEBUG_TS(("nomadik_tsc2003_init_irq\n"));
++ err = STMPE2401_SetGpioAltFunction( STMPE1 , EGPIO_PIN_6 , STMPE2401_PRIMARY_FUNCTION );
++ err |= STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_6,STMPE2401_GPIO_IN );
++ err |= STMPE2401_SetGpioPull(STMPE1,EGPIO_PIN_6,STMPE2401_FLOATING );
++
++ err = STMPE2401_Install_Callback(STMPE1, STMPE2401_GPIO_IRQ(6), callback,(void*)p);
++ if (err != STMPE2401_OK) {
++ printk("Couldn't setup touch screen callback\n");
++ }
++ err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_FALL_EDGE);
++ if (err != STMPE2401_OK) {
++ printk("Couldn't set touch screen edge detection\n");
++ }
++ err = STMPE2401_ClearGpioEdgeStatus(STMPE1,(0x1<<EGPIO_PIN_6));
++ if (err != STMPE2401_OK) {
++ printk("Couldn't clear touch screen edge status \n");
++ }
++ /*err = STMPE2401_InterruptAbilitation(STMPE1, STMPE2401_ENABLE_INTERRUPT );
++ if (err != STMPE2401_OK) {
++ printk("Couldn't enable touch screen callback\n");
++ }*/
++ return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_exit_irq(void)
++{
++ t_STMPE2401_error err;
++ DEBUG_TS(("nomadik_tsc2003_exit_irq\n"));
++ err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
++ err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_NO_EDGE);
++ return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_irqen(void)
++{
++ t_STMPE2401_error err;
++ //DEBUG_TS(("nomadik_tsc2003_irqen\n"));
++ err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_ENABLE_INTERRUPT );
++ return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_irqdis(void)
++{
++ t_STMPE2401_error err;
++ //DEBUG_TS(("nomadik_tsc2003_irqdis\n"));
++ err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
++ return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_irq_ack(void)
++{
++ u16 irqSource = 0x100;
++ u32 irqGpioSource = 0x40;
++ t_STMPE2401_error err;
++ //DEBUG_TS(("nomadik_tsc2003_irq_ack\n"));
++ err = STMPE2401_Acknowledge(STMPE1,irqSource,irqGpioSource);
++ return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_read_pin_val(u8 * Value)
++{
++ t_STMPE2401_error err;
++
++ err = STMPE2401_GetGpioVal(STMPE1 , EGPIO_PIN_6, Value);
++ return (err != STMPE2401_OK);
++}
++static struct touchp_tsc2003_device touchp_tsc2003_board = {
++ .irq_init = nomadik_tsc2003_init_irq,
++ .irq_exit = nomadik_tsc2003_exit_irq,
++ .pirq_en = nomadik_tsc2003_irqen,
++ .pirq_dis = nomadik_tsc2003_irqdis,
++ .pirq_ack = nomadik_tsc2003_irq_ack,
++ .pirq_read_val = nomadik_tsc2003_read_pin_val,
++};
++
++static struct platform_device touchp_tsc2003_device = {
++ //.name = "nmdk-tp",
++ .name = "tsc2003",
++ .id = 0,
++ .dev = {
++ .platform_data = &touchp_tsc2003_board,
++ },
++ .num_resources = 0,
++ .resource = NULL,
++};
++
++/*
++ * keypad
++ */
++
++#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++static void kp_callback (void * parameter)
++{
++ t_STMPE2401_error err;
++ t_STMPE2401_key_status keys;
++ struct keypad_t * kp = (struct keypad_t *)parameter;
++ u8 kcode,i;
++
++ /*DEBUG_KP(("kp_callback\n"));*/
++ err = STMPE2401_Keypressed(STMPE0, &keys);
++ if(keys.buttonPressed)
++ {
++ for(i=0;i<keys.buttonPressed;i++)
++ {
++ kcode = kp->board->kcode_tbl[(keys.button[i]&0x3)*4 + ((keys.button[i]>>3)&0x3)];
++ input_report_key(kp->inp_dev,kcode, 1);
++ }
++ }
++ if(keys.buttonReleased)
++ {
++ for(i=0;i<keys.buttonReleased;i++)
++ {
++ kcode = kp->board->kcode_tbl[(keys.released[i]&0x3)*4 + ((keys.released[i]>>3)&0x3)];
++ input_report_key(kp->inp_dev,kcode, 0);
++ }
++ }
++}
++
++/**
++ * nomadik_kp_init_key_hardware - keypad hardware initialization
++ *
++ ****************************************************************************
++ */
++int nomadik_kp_init_key_hardware(struct keypad_t *kp)
++{
++ t_STMPE2401_error err;
++ t_STMPE2401_key_config kpconfig;
++
++ DEBUG_KP(("nomadik_kp_init_key_hardware\n"));
++ nmdk_dbg_ftrace();
++ /*setup Columns GPIOs (inputs)*/
++ kpconfig.columns = 0xF; //4 columns
++ kpconfig.rows = 0xF; //4 rows
++ kpconfig.nCycles = 8; //number of cycles for key data updating
++ kpconfig.debounce = 64; //de-bounce time 64 ms
++ kpconfig.scan = STMPE2401_SCAN_OFF;
++ err = STMPE2401_Keypad_init(STMPE0, kpconfig);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't setup keypad configuration\n");
++ }
++ if (!kp->mode)
++ { /* true if interrupt mode operation */
++ DEBUG_KP(("\tsetting up keypad interrupt stuff\n"));
++ err = STMPE2401_Install_Callback(STMPE0, STMPE2401_KEYPAD_IRQ,kp_callback,(void*)kp);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't setup keypad callback\n");
++ }
++ err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't abilitate the keypad source interrupt\n");
++ }
++ /*err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_ENABLE_INTERRUPT );
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't enable the keypad source interrupt\n");
++ }*/
++ }
++ err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_ON);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't enable keypad scan\n");
++ }
++ return 0;
++}
++
++/**
++ * nomadik_kp_exit_key_hardware- keypad hardware exit function
++ *
++ */
++int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
++{
++ t_STMPE2401_error err;
++
++ DEBUG_KP(("nomadik_kp_exit_key_hardware\n"));
++ err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_OFF);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't enable keypad scan\n");
++ }
++ if (!kp->mode)
++ { /* true if interrupt mode operation */
++ err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_DISABLE_INTERRUPT );
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't disable keypad callback\n");
++ }
++ err = STMPE2401_Remove_Callback(STMPE0, STMPE2401_KEYPAD_IRQ);
++ if (err != STMPE2401_OK)
++ {
++ printk("Couldn't remove keypad callback\n");
++ }
++ }
++ nmdk_dbg_ftrace();
++ return 0;
++}
++
++/**
++ * nomadik_kp_key_scan - keypad scan and report event function
++ *
++ */
++int nomadik_kp_key_scan(struct keypad_t *kp)
++{
++ DEBUG_KP(("nomadik_kp_key_scan\n"));
++ kp_callback ((void *) kp);
++ return 0;
++}
++
++/**
++ * nomadik_kp_key_irqen- enables keypad interrupt
++ *
++ * enables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqen(struct keypad_t *kp)
++{
++ t_STMPE2401_error err;
++ DEBUG_KP(("nomadik_kp_key_irqen\n"));
++ err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
++ return (err != STMPE2401_OK);
++}
++
++/**
++ * nomadik_kp_key_irqdis- disables keypad interrupt
++ *
++ * disables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqdis(struct keypad_t *kp)
++{
++ t_STMPE2401_error err;
++ DEBUG_KP(("nomadik_kp_key_irqdis\n"));
++ err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_DISABLE_INTERRUPT );
++ return (err != STMPE2401_OK);
++}
++
++/*
++ * Initializes the key scan table (lookup table) as per pre-defined the scan
++ * codes to be passed to upper layer with respective key codes
++ */
++u8 const kpd_lookup_tbl[4*4] = {
++ KEY_RESERVED, KEY_RESERVED, KEY_VOLUMEDOWN, KEY_VOLUMEUP,
++ KEY_F1, KEY_F8, KEY_F3, KEY_F4,
++ KEY_F5, KEY_F6, KEY_F7, KEY_ENTER,
++ KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN
++};
++
++static struct keypad_device keypad_board = {
++ .init = nomadik_kp_init_key_hardware,
++ .exit = nomadik_kp_exit_key_hardware,
++ .scan = nomadik_kp_key_scan,
++ .irqen = nomadik_kp_key_irqen,
++ .irqdis = nomadik_kp_key_irqdis,
++ .kcode_tbl = (u8 *) kpd_lookup_tbl,
++ .krow = 4,
++ .kcol = 4,
++};
++
++#undef NMDK_DEBUG /*board*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++
++/*static struct resource keypad_resources[] = {
++ [0] = {
++ },
++};*/
++
++static struct platform_device keypad_device = {
++ .name = "nmdk-kp",
++ .id = 0,
++ .dev = {
++ .platform_data = &keypad_board,
++ },
++ .num_resources = 0,
++ .resource = NULL,
++};
++
++static struct platform_device *nmdk_platform_devices[] __initdata = {
++ &fsmc_device,
++ &nomadik_udc_device,
++#ifdef CONFIG_MTD
++#ifdef CONFIG_MTD_NAND
++ &nomadik_nand_flash,
++#endif
++#ifdef CONFIG_MTD_ONENAND
++ &nomadik_1nand_flash,
++#endif
++#endif
++#ifdef CONFIG_SMC91X
++ &smc91x_device,
++#endif
++#ifdef CONFIG_STMPE_NOMADIK
++ &nomadik_stmpe_device,
++#endif
++ &keypad_device,
++ &touchp_tsc2003_device,
++};
++
++void add_nmdk_platform_devices(void)
++{
++ platform_add_devices(nmdk_platform_devices,
++ ARRAY_SIZE(nmdk_platform_devices));
++}
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/normal.S
+@@ -0,0 +1,199 @@
++/*
++ * arch/arm/mach-nomadik/normal.S
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#define NORMAL_DEBUG 0
++#define mpmc_base 0xF0110000
++#define src_base 0xf01e0000
++#define pmu_base 0xf01e9000
++#define uart_base 0xcc85e000
++
++
++
++
++.align 5
++.globl nomadik_normal_mode
++
++nomadik_normal_mode:
++
++
++ stmfd sp!,{r0-r12,lr}
++
++ ldr r10,=mpmc_base
++ ldr r11,=src_base
++ ldr r12,=pmu_base
++ ldr r9,=uart_base
++
++
++ ldr r2, [r11]
++
++#if NORMAL_DEBUG
++ mov r0, #97
++ str r0, [r9]
++#endif
++
++ /* Prefetch certain instructions in the cache. */
++ adr r4, cache_prefetch_start
++ adr r5, cache_prefetch_end
++ mvn r1,#0x1F
++ ands r4,r1,r4
++pfetch:
++ mcr p15, 0, r4, c7, c13,1
++ cmp r4,r5
++ addls r4, r4, #0x20
++ bls pfetch
++
++.align 5
++
++cache_prefetch_start:
++ ldr r10, =mpmc_base
++
++poll_status:
++ /* Check sdram is not busy */
++ ldr r1,[r10, #0x4]
++ ands r1,r1,#0x1
++ cmp r1,#0
++ bne poll_status
++
++ /* Put SDRAM in self-refresh mode*/
++ ldr r1,[r10, #0x20]
++ bic r1,r1,#0x1
++ orr r1,r1,#0x04
++ str r1,[r10, #0x20]
++
++
++ /*Wait for SDRAM to go in self-refresh*/
++wait_self_refresh:
++ ldr r1,[r10,#0x4]
++ and r1,r1,#0x4
++ cmp r1,#0x0
++ beq wait_self_refresh
++
++ /**
++ * Stop the DLL, leave SDMC on
++ Moving 0xff9 into sdmc control register for stopping and adding dll
+ cmd value
+ */
+ mov r1, #0xff0
+ cmp r1,#0
+ bne wait_dll_lock
+
-+#if NORMAL_DEBUG
++#if NORMAL_DEBUG
+ mov r0, #98
+ str r0, [r9]
+#endif
+
+
+
-+#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
+ bne wait_normal_mode
+
+
-+#if NORMAL_DEBUG
++#if NORMAL_DEBUG
+ mov r0, #100
+ str r0, [r9]
+#endif
+
+ /* Exit DDR-SDRAM from self-refresh mode */
+ ldr r1,[r10, #0x20]
-+ bic r1,r1,#0x04
++ bic r1,r1,#0x04
+ str r1,[r10, #0x20]
+
+
+ and r1,r1,#0x4
+ cmp r1,#0x4
+ beq loop_refresh
-+
-+#if NORMAL_DEBUG
++
++#if NORMAL_DEBUG
+ mov r0, #101
+ str r0, [r9]
+#endif
+ mov r0,r0
+
+
-+#if NORMAL_DEBUG
++#if NORMAL_DEBUG
+
+ mov r0, #102
+ str r0, [r9]
+ 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
+}
+
+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
+
+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
+ {
+ int tmp = 0;
+
-+ /*
++ /*
+ * The max we can do is 8192Hz.
+ */
+ if ((arg < 2) || (arg > 8192))
+MODULE_AUTHOR("Prafulla WADASKAR <prafulla.wadaskar@st.com>");
+MODULE_DESCRIPTION("Nomadik RTC/RTT driver");
+MODULE_LICENSE("GPL v2");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/sleep.c ../new/linux-2.6.20/arch/arm/mach-nomadik/sleep.c
---- linux-2.6.20/arch/arm/mach-nomadik/sleep.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/sleep.c 2008-08-21 18:04:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/sleep.c
@@ -0,0 +1,280 @@
+/*
+ * arch/arm/mach-nomadik/sleep.c
+
+ 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
+ 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
+ bls pfetch
+
+.align 5
-+
++
+cache_prefetch_start:
+ ldr r10, =mpmc_base
+
+ 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
+
+ /**
+ * 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
+ cmp r1,#0
+ bne wait_dll_lock
+
-+#if SLOW_DEBUG
++#if SLOW_DEBUG
+ mov r0, #98
+ str r0, [r9]
+#endif
+
+
+
-+#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
+*/
+
+#endif
+
-+#if SLOW_DEBUG
++#if SLOW_DEBUG
+ mov r0, #100
+ str r0, [r9]
+#endif
+
+ /* Exit DDR-SDRAM from self-refresh mode */
+ ldr r1,[r10, #0x20]
-+ bic r1,r1,#0x04
++ bic r1,r1,#0x04
+ str r1,[r10, #0x20]
+
+
+ and r1,r1,#0x4
+ cmp r1,#0x4
+ beq loop_refresh
-+
-+#if SLOW_DEBUG
++
++#if SLOW_DEBUG
+ mov r0, #101
+ str r0, [r9]
+#endif
+ mov r0,r0
+
+
-+#if SLOW_DEBUG
++#if SLOW_DEBUG
+
+ mov r0, #102
+ str r0, [r9]
+ 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
+
+
+ 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
+ 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
+
+.align 5
+
-+
++
+cache_prefetch_start:
+ ldr r10, =mpmc_base
+
+ 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
+ and r1,r1,#0x4
+ cmp r1,#0x0
+ beq wait_self_refresh
-+
++
+/** Routine to put the chip in Sleep Mode
+*/
+ ldr r11,=src_base
+
+
+/* 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]
+ mov r0,r0
+ mov r0,r0
+ mov r0,r0
-+
++
+/* This is to add some delay */
+ mov r0, #0
+while_loop:
+ 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
+MODULE_AUTHOR("Sachin Verma, <sachin.verma@st.com>");
+MODULE_DESCRIPTION("NOMADIK SPI Controller Driver");
+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c 2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c
@@ -0,0 +1,1071 @@
+/*
+ * linux/arch/arm/mach-nomadik/stn8810_devices.c
+
+/**
+ * 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",
+
+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 = {
+#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);
+
+ .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. */
+ 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
+ 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)) {
+ .dyn_tick = &nomadik_dyn_tick,
+#endif
+};
-diff -Nauprw linux-2.6.20/arch/arm/Makefile ../new/linux-2.6.20/arch/arm/Makefile
---- linux-2.6.20/arch/arm/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -20,7 +20,7 @@ CFLAGS +=$(call cc-option,-marm,)
-
- # Do not use arch/arm/defconfig - it's always outdated.
- # Select a platform tht is kept up-to-date
--KBUILD_DEFCONFIG := versatile_defconfig
-+KBUILD_DEFCONFIG := ndk15_defconfig
-
- # defines filename extension depending memory manement type.
- ifeq ($(CONFIG_MMU),)
-@@ -89,6 +89,7 @@ CHECKFLAGS += -D__arm__
- head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
- textofs-y := 0x00008000
-
-+
- machine-$(CONFIG_ARCH_RPC) := rpc
- machine-$(CONFIG_ARCH_EBSA110) := ebsa110
- machine-$(CONFIG_ARCH_CLPS7500) := clps7500
-@@ -106,6 +107,7 @@ endif
- machine-$(CONFIG_ARCH_PXA) := pxa
- machine-$(CONFIG_ARCH_L7200) := l7200
- machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
-+ machine-$(CONFIG_ARCH_NOMADIK) := nomadik
- textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
- machine-$(CONFIG_ARCH_CLPS711X) := clps711x
- machine-$(CONFIG_ARCH_IOP32X) := iop32x
-@@ -200,12 +202,21 @@ else
- endif
- @touch $@
-
--archprepare: maketools
-+archprepare: maketools machprepare
-
--PHONY += maketools FORCE
-+PHONY += maketools machprepare machclean machmrproper FORCE
- maketools: include/linux/version.h include/asm-arm/.arch FORCE
- $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
-
-+
-+# Machine specific preparation if it exists
-+MACHPREPARE_PATH = $(strip `grep "machprepare:" $(MACHINE)Makefile* | grep -o $(MACHINE)`)
-+
-+machprepare:
-+ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
-+ $(Q)set -e; for i in $(MACHPREPARE_PATH); do $(MAKE) -C $$i $@; done
-+endif
-+
- # Convert bzImage to zImage
- bzImage: zImage
-
-@@ -218,8 +229,23 @@ zinstall install: vmlinux
- CLEAN_FILES += include/asm-arm/mach-types.h \
- include/asm-arm/arch include/asm-arm/.arch
-
-+# Machine specific mrproper operation if it exists
-+MACHMRPROPER_PATH =`find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machmrproper: | sed 's/Makefile:machmrproper://g' | sed 's/Makefile://g'`
-+
-+machmrproper:
-+ $(Q)set -e; for i in $(MACHMRPROPER_PATH); do $(MAKE) -C $$i $@; done
-+
-+# We use MRPROPER_FILES
-+archmrproper: machmrproper
-+
-+# Machine specific clean operation
-+MACHCLEAN_PATH = `find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machclean: | sed 's/Makefile:machclean://g' | sed 's/Makefile://g'`
-+
-+machclean:
-+ $(Q)set -e; for i in $(MACHCLEAN_PATH); do $(MAKE) -C $$i $@; done
-+
- # We use MRPROPER_FILES and CLEAN_FILES now
--archclean:
-+archclean: machclean
- $(Q)$(MAKE) $(clean)=$(boot)
-
- # My testing targets (bypasses dependencies)
-diff -Nauprw linux-2.6.20/arch/arm/mm/extable.c ../new/linux-2.6.20/arch/arm/mm/extable.c
---- linux-2.6.20/arch/arm/mm/extable.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/extable.c 2007-11-21 11:51:41.000000000 +0530
-@@ -2,6 +2,7 @@
- * linux/arch/arm/mm/extable.c
- */
- #include <linux/module.h>
-+#include <linux/kgdb.h>
- #include <asm/uaccess.h>
-
- int fixup_exception(struct pt_regs *regs)
-@@ -11,6 +12,12 @@ int fixup_exception(struct pt_regs *regs
- fixup = search_exception_tables(instruction_pointer(regs));
- if (fixup)
- regs->ARM_pc = fixup->fixup;
-+#ifdef CONFIG_KGDB
-+ if (atomic_read(&debugger_active) && kgdb_may_fault)
-+ /* Restore our previous state. */
-+ kgdb_fault_longjmp(kgdb_fault_jmp_regs);
-+ /* Not reached. */
-+#endif
-
- return fixup != NULL;
- }
-diff -Nauprw linux-2.6.20/arch/arm/mm/init.c ../new/linux-2.6.20/arch/arm/mm/init.c
---- linux-2.6.20/arch/arm/mm/init.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/init.c 2007-11-21 11:51:41.000000000 +0530
-@@ -89,7 +89,6 @@ void show_mem(void)
- printk("%d pages shared\n", shared);
- printk("%d pages swap cached\n", cached);
- }
--
- /*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd. Hopefully, this is located towards
-diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kconfig
---- linux-2.6.20/arch/arm/mm/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -60,7 +60,7 @@ config CPU_ARM710
+--- linux-2.6.20.orig/arch/arm/mm/Kconfig
++++ linux-2.6.20/arch/arm/mm/Kconfig
+@@ -58,11 +58,11 @@ config CPU_ARM710
+ Say Y if you want support for the ARM710 processor.
+ Otherwise, say N.
# ARM720T
config CPU_ARM720T
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"
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
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.
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"
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"
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"
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"
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"
select CPU_32v6
select CPU_ABRT_EV6
select CPU_CACHE_V6
-diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm/mm/proc-arm926.S
---- linux-2.6.20/arch/arm/mm/proc-arm926.S 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/proc-arm926.S 2008-10-20 13:37:44.000000000 +0530
-@@ -24,6 +24,10 @@
+ select CPU_CACHE_VIPT
+ select CPU_CP15_MMU
+--- linux-2.6.20.orig/arch/arm/mm/extable.c
++++ linux-2.6.20/arch/arm/mm/extable.c
+@@ -1,16 +1,23 @@
+ /*
+ * linux/arch/arm/mm/extable.c
+ */
+ #include <linux/module.h>
++#include <linux/kgdb.h>
+ #include <asm/uaccess.h>
+
+ int fixup_exception(struct pt_regs *regs)
+ {
+ const struct exception_table_entry *fixup;
+
+ fixup = search_exception_tables(instruction_pointer(regs));
+ if (fixup)
+ regs->ARM_pc = fixup->fixup;
++#ifdef CONFIG_KGDB
++ if (atomic_read(&debugger_active) && kgdb_may_fault)
++ /* Restore our previous state. */
++ kgdb_fault_longjmp(kgdb_fault_jmp_regs);
++ /* Not reached. */
++#endif
+
+ return fixup != NULL;
+ }
+--- linux-2.6.20.orig/arch/arm/mm/init.c
++++ linux-2.6.20/arch/arm/mm/init.c
+@@ -87,11 +87,10 @@ void show_mem(void)
+ printk("%d reserved pages\n", reserved);
+ printk("%d slab pages\n", slab);
+ printk("%d pages shared\n", shared);
+ printk("%d pages swap cached\n", cached);
+ }
+-
+ /*
+ * FIXME: We really want to avoid allocating the bootmap bitmap
+ * over the top of the initrd. Hopefully, this is located towards
+ * the start of a bank, so if we allocate the bootmap bitmap at
+ * the end, we won't clash.
+--- linux-2.6.20.orig/arch/arm/mm/proc-arm926.S
++++ linux-2.6.20/arch/arm/mm/proc-arm926.S
+@@ -22,19 +22,24 @@
+ *
+ * These are the low level assembler for performing cache and TLB
* functions on the arm926.
*
* CONFIG_CPU_ARM926_CPU_IDLE -> nohlt
*/
#include <linux/linkage.h>
#include <linux/init.h>
-@@ -33,6 +37,7 @@
+ #include <asm/assembler.h>
+ #include <asm/elf.h>
+ #include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#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............
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
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
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
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
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
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;
return ret;
}
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,66 @@
-+
-+ * 1.1 Nomadik Development Debugging Strategy
-+ * ==========================================
-+ *
-+ * DEBUGGING LEVELS
-+ * 0 To disable all debug messages
-+ * 1 To enable normal debug macro- nmdk_dbg
-+ * 2 To enable flow trace debug macro- nmdk_dbg_ftrace
-+ * 4 To enable interrupt and timer debug macroc- nmdk_dbg2
-+ * 8 To enable any special debug messages defined by macro- nmdk_dbg3
-+ *
-+ *
-+ * 1.2 How to use Debuggign strategy in driver development ?
-+ * =========================================================
-+ *
-+ * 1. include debug-nomadik.h file in c code
-+ * (path: include/asm-arm/arch/nomadik/debug-nomadik.h)
-+ * 2. define NMDK_DEBUG to required debug level (this can be automated
-+ * to pass build time debug levels -as done for keypad driver.
-+ * See driver/input/keypad makefile)
-+ * 3. define NMDK_DEBUG_PFX to a small string to identify debug message
-+ * This is an optional setting, if you don't define NMDK_DEBUG_PFX,
-+ * by default "Nomadik" will be selected.
-+ * 4. define NMDK_DBG to desired Kerlen debug level
-+ * This is an optional setting, if you don't define NMDK_DBG,
-+ * by default KERN_DEBUG will be used
-+ * This generally need to set to KERN_ERR to force debug messages to
-+ * appear on the console
-+ *
-+ *
-+ * 1.3 How to activate debug messages?
-+ *====================================
-+ *
-+ * Debug messages can be activated during build time by passing desired
-+ * debug level either hardcoding in source file or as a make parameter
-+ *
-+ * 1. Enabling Debug messages by passing additional parameter to make
-+ * This is a recommended method of debug messages implimentation.
-+ * this method give flexibility to enable/disable debug messages
-+ * during build without modifying code
-+ * (a) To enable this you need to updated driver make file with:-
-+ * ex.
-+ * ifdef <DRVNAME>_DEBUG
-+ * CFLAGS += -<DRVNAME>_DEBUG=$(<DRVNAME>_DEBUG)
-+ * endif
-+ *
-+ * (b) Same <DRVNAME>_DEBUG must be used to define NMDK_DEBUG as
-+ * explained in (1.2.2)
-+ * (c) Debug parameter must be passed to the make with desired debug
-+ * level as explained in (1.1)
-+ * ex. make <DRVNAME>_DEBUG=1
-+ * (d) you can AND several debug levels togather to enable respective
-+ * debug mesages
-+ * (e) even you can pass additional parameters to enable debug messages
-+ * of more than one module
-+ * ex. make <DRV1>_DEBUG=1 <DRV2>_DEBUG=4 ...
-+ *
-+ * 2. Enabling Debug messages by hardcoding in source file
-+ * This is simplest implimentation, just define NMDK_DEBUG to
-+ * desired debug level and compile the code, the disadvantage of this
-+ * method is, it does not offer flexibility and code with debug message
-+ * may become part of your release if not taken care properly.
-+ *
-+ */
+ void oprofile_arch_exit(void)
+ {
+--- linux-2.6.20.orig/drivers/Makefile
++++ linux-2.6.20/drivers/Makefile
+@@ -3,10 +3,11 @@
+ #
+ # 15 Sep 2000, Christoph Hellwig <hch@infradead.org>
+ # Rewritten to use lists instead of if-statements.
+ #
+
++obj-$(CONFIG_I2C) += i2c/
+ obj-$(CONFIG_PCI) += pci/
+ obj-$(CONFIG_PARISC) += parisc/
+ obj-$(CONFIG_RAPIDIO) += rapidio/
+ obj-y += video/
+ obj-$(CONFIG_ACPI) += acpi/
+@@ -55,11 +56,10 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/
+ obj-$(CONFIG_SERIO) += input/serio/
+ obj-$(CONFIG_GAMEPORT) += input/gameport/
+ obj-$(CONFIG_INPUT) += input/
+ obj-$(CONFIG_I2O) += message/
+ obj-$(CONFIG_RTC_LIB) += rtc/
+-obj-$(CONFIG_I2C) += i2c/
+ obj-$(CONFIG_W1) += w1/
+ obj-$(CONFIG_HWMON) += hwmon/
+ obj-$(CONFIG_PHONE) += telephony/
+ obj-$(CONFIG_MD) += md/
+ obj-$(CONFIG_BT) += bluetooth/
+--- linux-2.6.20.orig/drivers/char/keyboard.c
++++ linux-2.6.20/drivers/char/keyboard.c
+@@ -1181,10 +1181,11 @@ static void kbd_keycode(unsigned int key
+ }
+ if (sysrq_down && !down && keycode == sysrq_alt_use)
+ sysrq_down = 0;
+ if (sysrq_down && down && !rep) {
+ handle_sysrq(kbd_sysrq_xlate[keycode], tty);
++ sysrq_down = 0; /* In case we miss the 'up' event. */
+ return;
+ }
+ #endif
+ #ifdef CONFIG_SPARC
+ if (keycode == KEY_A && sparc_l1_a_state) {
+--- linux-2.6.20.orig/drivers/cpufreq/Kconfig
++++ linux-2.6.20/drivers/cpufreq/Kconfig
+@@ -138,6 +138,10 @@ config CPU_FREQ_GOV_CONSERVATIVE
+
+ For details, take a look at linux/Documentation/cpu-freq.
+
+ If in doubt, say N.
+
++config CPU_FREQ_NOMADIK
++ tristate "cpu freq scaling support for nomadik"
++ depends on CPU_FREQ
+
+ endif # CPU_FREQ
+--- linux-2.6.20.orig/drivers/hwmon/Kconfig
++++ linux-2.6.20/drivers/hwmon/Kconfig
+@@ -228,10 +228,23 @@ config SENSORS_IT87
+ IT8716F and IT8718F sensor chips, and the SiS960 clone.
+
+ This driver can also be built as a module. If so, the module
+ will be called it87.
+
++config SENSORS_LIS3LV02DL
++ tristate "LIS3LV02DL MEMS three-axis accelerometer I2C driver"
++ depends on HWMON && I2C && EXPERIMENTAL
++ default n
++ help
++ This driver provides support for the ST microelectronics LIS3LV02DL
++ MEMS inertial sensor which provides a three-axis, I2C controlled
++ ± 2g/± 6g digital output linear accelerometer. The accelerometer
++ data is readable via sysfs.
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,420 @@
-+Filename: ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
-+Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner: STMicroelectronics
-+Purpose:
-+ This Users Guide explains DMA implimentation and its usage
-+ for client drivers on Nomadik platforms
-+=============================================================================
++ This driver can also be built as a module. If so, the module
++ will be called lis3vl02dl.
+
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
-+2. you are familier with Kernal DMA interface
-+ (References: ./Documentation/DMA-API.txt)
+ config SENSORS_LM63
+ tristate "National Semiconductor LM63"
+ depends on HWMON && I2C
+ help
+ If you say yes here you get support for the National Semiconductor
+--- linux-2.6.20.orig/drivers/hwmon/Makefile
++++ linux-2.6.20/drivers/hwmon/Makefile
+@@ -28,10 +28,11 @@ obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
+ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
+ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
+ obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
+ obj-$(CONFIG_SENSORS_IT87) += it87.o
+ obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
++obj-$(CONFIG_SENSORS_LIS3LV02DL)+= lis3lv02dl.o
+ obj-$(CONFIG_SENSORS_LM63) += lm63.o
+ obj-$(CONFIG_SENSORS_LM70) += lm70.o
+ obj-$(CONFIG_SENSORS_LM75) += lm75.o
+ obj-$(CONFIG_SENSORS_LM77) += lm77.o
+ obj-$(CONFIG_SENSORS_LM78) += lm78.o
+--- /dev/null
++++ linux-2.6.20/drivers/hwmon/lis3lv02dl.c
+@@ -0,0 +1,489 @@
++/*
++ stmems.c
+
-+DMA Configuration:
-+===================
-+By default Nomadik DMA driver is configured to link staticlly with kernel.
-+This DMA driver provides low level interface to the kernel DMA interface.
-+To use DMA APIs, client driver should only include <asm/dma.h>
++ Copyright (c) 2008 Nicholas Angelo Crespi <roundtrip@gmail.com>
+
-+Definations:
-+============
-+1. DMA Channel: The logical DMA channel can be used for a DMA transfer
-+2. Pipe: the physical DMA chanel H/w that is used to a DMA transfer
-+3. DMAC: Direct Memory Access Controller (Nomadik has two DMACs)
++ LIS3LV02DL MEMS inertial sensor is a 3-axis - ± 2g/± 6g digital output
++ low voltage linear accelerometer.
++ http://www.st.com/stonline/products/literature/ds/12094/lis3lv02dl.htm
+
-+Brief Architecture:
-+===================
-+DMA dirver is registered as amba device and will be probed only if
-+matches peripharal ID, the SOC specific data/function iterface is provided
-+through platfrom_data pointer to allign driver design in sync with multiboard
-+strategy.
-+There are two DMA controllers having 8 pipes each, there could be number of
-+dma channels which will use any one available pipe for dma transfer at run time
-+Kernel DMA interface defines and controls the interface, whereas the h/w
-+specific APIs are mapped through methods provided by upper layer (i,e.
-+arch/arm/kernel/dma.c). The configuration, usage and features provided by this
-+driver is explained below.
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
+
-+This Users guide explains-
-+1. Support for Standard DMA APIs for Nomadik DMA usage
-+2. Additional DMA APIs to facilitate effieient/flexible DMA usage
-+3. DMA Channel configuration.
-+ a) Mode of operation: Transfer type
-+ b) Mode of operation: flow control
-+ c) Mode of operation: Double Buffered Transfer
-+ d) Mode of operation: Infinite DMA Transfer
-+ e) Mode of operation: Infinite DMA Transfer
-+ f) Mode of operation: Pipe reservation
-+ g) Mode of operation: Channel Priority
-+ h) Mode of operation: Queueing DMA transfer requests
-+4. DMA Interrupt hanndling for callback functions.
-+5. Scatter-gather Support
-+6. /proc/dma interfce.
-+7. HOWTO add new DMAable peripharal device support
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
+
-+1. Support for Standard DMA APIs for Nomadik DMA usage
-+======================================================
-+Standard kernel DMA interface exports APIs out of which request_dma, enable_dma,
-+disable_dma, free_dma, dma_channel_active, set_dma_sg, __set_dma_addr, set_dma_count,
-+are supported for Nomadik DMA Usage.
-+For any DMA transfer you need to follow a sequence-
-+ a) request_dma : to request a DMA channel be to used for transfer,
-+ in this request you need to pass configuration
-+ b) request_irq : to register DMA callback function
-+ c) __set_dma_srcaddr : to set src DMAble address (mapped to __set_dma_addr)
-+ d) __set_dma_destaddr : to set dest DMAble address (mapped to set_dma_speed)
-+ e) set_dma_count : to set transfer size in bytes
-+ f) set_dma_mode : to set/ulter mode of operation (optional)
-+ g) enable_dma : to start transfer
-+ h) dma_channel_active : to know the status of scheduled transfer (optional)
-+ i) disable dma : to stop transfer (optional)
-+ j) free_irq : to free irq used for callback (optional)
-+ k) free_dma : to free requested DMA channel
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
-+2. Additional DMA APIs for effieient/flexible DMA usage
-+=======================================================
-+Following additional APIs are provided for effieient/flexible DMA usage
-+ a) request_available_dma
-+ : This is a wrapper over request_dma,
-+ this API will search, allocate and return available
-+ free DMA channel.
-+ b) suspend_DMA : to pause currently active DMA transfer
-+ c) resume_DMA : to resume previously paused DMA transfer
++ * Compile this driver with:
+
-+3. DMA Channel Configureation:
-+==============================
-+Durring request_dma system call you need to pass a pointer of pre-filled DMA
-+Channel configuration structure nmdk_dma_info defined in asm/arch/dma.h
-+i.e.-
-+struct nmdk_dma_info {
-+ u32 mode; /* Mode of operation(xfer type/flow cntrl etc)*/
-+ char *srcdevtype; /* source device type configuration*/
-+ char *destdevtype; /* desitnation device type configuration*/
-+ u32 config; /* User programmable dmadev configuration*/
-+};
++ echo "obj-m := tiny_i2c_chip.o" > Makefile
++ make -C <path/to/kernel/src> SUBDIRS=$PWD modules
++ */
+
-+Each DMA channle has source DMA device and a destination DMA device, a DMA
-+channel is a hardware that connects two DMAable devices for data transfer.
-+So to have a successfull DMA transfer you need to configure all these three.
-+Below picture gives some idea about it-
++#define DEBUG 1
++#define VERSION "0.2"
+
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <asm/arch/i2c.h>
+
-+ --------------------
-+ srcdevtype, src_addr | | destdevtype, dest_addr
-+ def dmadev config | | default dmadev configuration
-+ | |
-+ (Src DMA periph)------>| DMA Channel |--------> (Dest DMA peripharal)
-+ | |
-+ --------------------
-+ (mode of operation)
-+ (User configuration)
-+ (Xfer Size in bytes)
++#define stmems_perror(format, arg...)
++//printk( KERN_ERR "STMEMS: %s " format, __func__, ## arg)
++#define stmems_pinfo(format, arg...)
++//printk( KERN_INFO "STMEMS: %s " format, __func__, ## arg)
+
-+DMAable devices and their default configurations are SOC specific and declared
-+in arch/arm/mach-nomadik/<SOC_NAME>_devices.c file (will be explained latter
-+in this guide). Each DMAble device is identified by unique name, during
-+configuration the src and dest dmadev names need to be specified.
++/* Addresses to scan */
+
-+Transfer Size in bytes, src_addr and dest_addr not a part of configuration as
-+they keeps changing and need to be provided before enable_dma request
++//static unsigned short normal_i2c[] = { 0x3A, I2C_CLIENT_END };
++static unsigned short normal_i2c[] = { 0x1D, I2C_CLIENT_END };
+
-+User programmable dmadev configuration: These are optional configuration on
-+the top of default for the changable paramters (specially Brust size and
-+transfer width). This will be exmpained latter in this guide
-+
-+for ex, to configure a dma chnnel for memory to MSP peripharal DMA transfer
-+the sructure should be filled as-
++//static unsigned short normal_i2c_range[] = { 0x00, 0xff, I2C_CLIENT_END };
+
-+ struct nmdk_dma_info test_dma_config =
-+ {
-+ .mode = MEM_TO_MEM,
-+ .srcdevtype = "mem",
-+ .destdevtype = "msp0rx",
-+ .config = NULL,
-+ };
-+
-+Out of all configuration parameter "mode" is very important since it decides
-+the mode of DMA channel operation, there are several features supported all
-+are configurable through mode.
++/* Insmod parameters */
++I2C_CLIENT_INSMOD_1(stmems);
+
-+ a) Mode of operation: Transfer type
-+ there are four basic modes of operation those are
-+ MEM_TO_MEM, MEM_TO_PERIPH, PERIPH_TO_MEM, PERIPH_TO_PERIPH
-+ you should program any one as per you need.
++/* Each client has this additional data */
++struct stmems_data {
++ struct i2c_client client;
++ struct class_device *class_dev;
++ struct mutex update_lock;
++ char valid; /* !=0 if following fields are valid */
++ unsigned long last_updated; /* In jiffies */
++ int acc_x; /* Register values */
++ int acc_y;
++ int acc_z;
++ u8 divisor;
++ u8 fullscale;
++ u8 BDU;
++};
+
-+ for ex. dma_info.mode=MEM_TO_PERIPH;
++/* stmems registers mnemonics */
++/* mnemonic hex r/w default */
++#define MEMS_WHO_AM_I 0x0F /*r 00111010 */
++#define MEMS_OFFSET_X 0x16 /*rw calib */
++#define MEMS_OFFSET_Y 0x17 /*rw calib */
++#define MEMS_OFFSET_Z 0x18 /*rw calib */
++#define MEMS_GAIN_X 0x19 /*rw calib */
++#define MEMS_GAIN_Y 0x1A /*rw calib */
++#define MEMS_GAIN_Z 0x1B /*rw calib */
++#define MEMS_CTRL_REG1 0x20 /*rw 00000111 */
++#define MEMS_CTRL_REG2 0x21 /*rw 00000000 */
++#define MEMS_CTRL_REG3 0x22 /*rw 00001000 */
++#define MEMS_HP_FILTER RESET 0x23 /*r dummy */
++#define MEMS_STATUS_REG 0x27 /*rw 00000000 */
++#define MEMS_OUTX_L 0x28 /*r */
++#define MEMS_OUTX_H 0x29 /*r */
++#define MEMS_OUTY_L 0x2A /*r */
++#define MEMS_OUTY_H 0x2B /*r */
++#define MEMS_OUTZ_L 0x2C /*r */
++#define MEMS_OUTZ_H 0x2D /*r */
++#define MEMS_FF_WU_CFG 0x30 /*rw 00000000 */
++#define MEMS_FF_WU_SRC 0x31 /*rw 00000000 */
++#define MEMS_FF_WU_ACK 0x32 /*r */
++#define MEMS_FF_WU_THS_L 0x34 /*rw 00000000 */
++#define MEMS_FF_WU_THS_H 0x35 /*rw 00000000 */
++#define MEMS_FF_WU_DURATION 0x36 /*rw 00000000 */
++#define MEMS_DD_CFG 0x38 /*rw 00000000 */
++#define MEMS_DD_SRC 0x39 /*rw 00000000 */
++#define MEMS_DD_ACK 0x3A /*r */
++#define MEMS_DD_THSI_L 0x3C /*rw 00000000 */
++#define MEMS_DD_THSI_H 0x3D /*rw 00000000 */
++#define MEMS_DD_THSE_L 0x3E /*rw 00000000 */
++#define MEMS_DD_THSE_H 0x3F /*rw 00000000 */
+
-+ b) Mode of operation: flow control
-+ By default flow controller is DMA controller, if you want to program
-+ flow controller as peripharal you can use the provided macros as
+
-+ for ex. dma_info.mode=FLOW_CNTRL_DMA(MEM_TO_PERIPH);
-+ To mention the flow controller is DMA controller.
++static int stmems_attach_adapter(struct i2c_adapter *adapter);
++static int stmems_detect(struct i2c_adapter *adapter, int address, int kind);
++static int stmems_detach_client(struct i2c_client *client);
++static void stmems_init_sensor(struct i2c_client *client);
++static inline u8 stmems_read_value(struct i2c_client *client, u8 reg);
++static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value);
++static inline int stmems_join(u8 LSB, u8 MSB);
++static struct stmems_data *stmems_update_device(struct device *dev);
+
-+ for ex. dma_info.mode=FLOW_CNTRL_PERIPH(MEM_TO_PERIPH);
-+ To mention the flow controller is peripharal controller.
++/* This is the driver that will be inserted */
++static struct i2c_driver stmems_driver = {
++ .driver = {
++ .name = "stmems",
++ },
++ .attach_adapter = stmems_attach_adapter,
++ .detach_client = stmems_detach_client,
++};
+
-+ Flow controller device cannot be peripharal for MEM_TO_MEM transter
++/* read routines for accelerations */
++#define show(value) \
++static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
++{ \
++ struct stmems_data *data = stmems_update_device(dev); \
++ return sprintf(buf, "%d\n", data->value); \
++}
++show(acc_x);
++show(acc_y);
++show(acc_z);
+
-+ c) Mode of operation: Double Buffered Transfer
-+ There are some peripharals like SAA(Smart Audio Accelerator) who
-+ requires DMA transfers to be done in double buffer mode, in double
-+ buffered mode of operation the current dma requested in divided in two,
-+ equal sequential transfers before scheduling.
++/* read routines for divisor, BDU and fullscale */
++static ssize_t show_divisor(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ if (!(data->valid))
++ data = stmems_update_device(dev);
++ return sprintf(buf, "%d\n", data->divisor);
++}
+
-+ By default standard single buffered transfer mode is programmed,
-+ to configure Double Buffered Transfer mode a macro DMA_DOUBLE_BUFFERED
-+ should be ORed with other configuration parameters
++static ssize_t show_fullscale(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ if (!(data->valid))
++ data=stmems_update_device(dev);
++ return sprintf(buf, "%d\n", data->fullscale);
++}
++static ssize_t show_BDU(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ if (!(data->valid))
++ data=stmems_update_device(dev);
++ return sprintf(buf, "%d\n", data->BDU);
++}
+
-+ for ex. dma_info.mode=DMA_DOUBLE_BUFFERED |
-+ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++/* this macro is useless! */
++#define set(value, reg) \
++static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
++{ \
++ struct i2c_client *client = to_i2c_client(dev); \
++ struct stmems_data *data = i2c_get_clientdata(client); \
++ int temp = simple_strtoul(buf, NULL, 10); \
++ \
++ mutex_lock(&data->update_lock); \
++ data->value = temp; \
++ mutex_unlock(&data->update_lock); \
++ return count; \
++}
+
-+ d) Mode of operation: Infinite DMA Transfer
-+ If you want to establish DMA transafer between two DMAble devices
-+ infinitely without CPUs intervention, this means once transfer is
-+ scheduled, it will reschedule it self at completion automatically.
++/* Write routines for divisor, BDU and fullscale */
++static ssize_t set_divisor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ u8 ctrl_reg;
++ int temp = simple_strtoul(buf, NULL, 10);
++ /* the divisor input can only be 512,128,32 or 8 */
++ if ((temp!= 8) && (temp!= 32) && (temp!= 128) && (temp!= 512)) return 0;
++ mutex_lock(&data->update_lock);
++ data->divisor = temp;
++ ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG1);
++ if (temp == 8) {ctrl_reg |= 0x30;}
++ else if (temp == 32) {ctrl_reg |= 0x20; ctrl_reg &= 0xEF;}
++ else if (temp == 128) {ctrl_reg |= 0x10; ctrl_reg &= 0xDF;}
++ else {ctrl_reg &= 0xCF; }
++ stmems_write_value(client,MEMS_CTRL_REG1,ctrl_reg);
++ mutex_unlock(&data->update_lock);
++ return count;
++}
+
-+ By default infinite DMA transfer is disabled,
-+ to configure Infinite DMA Transfer mode a macro DMA_INFINITE_XFER
-+ should be ORed with other configuration parameters
++static ssize_t set_fullscale(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ u8 ctrl_reg;
++ int temp = simple_strtoul(buf, NULL, 10);
++ if ((temp!= 1) && (temp!= 0)) return 0;
++ mutex_lock(&data->update_lock);
++ data->fullscale = temp;
++ ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
++ if (temp) {ctrl_reg |= 0x80;}
++ else {ctrl_reg &= 0x7F; }
++ stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
++ mutex_unlock(&data->update_lock);
++ return count;
++}
+
-+ for ex. dma_info.mode=DMA_INFINITE_XFER |
-+ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++static ssize_t set_BDU(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ u8 ctrl_reg;
++ int temp = simple_strtoul(buf, NULL, 10);
++ if ((temp!= 1) && (temp!= 0)) return 0;
++ mutex_lock(&data->update_lock);
++ data->BDU = temp;
++ ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
++ if (temp) {ctrl_reg |= 0x40;}
++ else {ctrl_reg &= 0xBF; }
++ stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
++ mutex_unlock(&data->update_lock);
++ return count;
++}
+
-+ In Infinite DMA transfer mode, you will never receive completion
-+ interrupt and callback interrupt handler cannot be executed
++static DEVICE_ATTR(acc_x, S_IRUGO,
++ show_acc_x, NULL);
++static DEVICE_ATTR(acc_y, S_IRUGO,
++ show_acc_y, NULL);
++static DEVICE_ATTR(acc_z, S_IRUGO,
++ show_acc_z, NULL);
+
-+ e) Mode of operation: Pipe reservation
-+ Reserving a pipe will dediate a pipe for a channel
-+ By default pipe is not reserved at the time of configuration. when you
-+ schedule a enable_dma request, system looks for the available pipe and
-+ schedules a transfer on it. This adds more flexibility to system to
-+ handle more channels on limited pipes. In case the all the pipes are
-+ busy the request will be deffered,
-+ if you want to avoid this behavior, i.e. whenever you request enable_dma
-+ pipe must be available to execute it, then you can reserve a pipe during
-+ configuration.
++static DEVICE_ATTR(fullscale, S_IWUSR | S_IRUGO,
++ show_fullscale, set_fullscale);
++static DEVICE_ATTR(divisor, S_IWUSR | S_IRUGO,
++ show_divisor, set_divisor);
++static DEVICE_ATTR(BDU, S_IWUSR | S_IRUGO,
++ show_BDU, set_BDU);
+
-+ to reserve a pipe, a macro DMA_PIPE_RESERVED
-+ should be ORed with other configuration parameters
++static int stmems_attach_adapter(struct i2c_adapter *adapter)
++{
++ int err;
+
-+ for ex. dma_info.mode=DMA_PIPE_RESERVED |
-+ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++ stmems_pinfo("entered\n");
++ stmems_pinfo("adapter class: %d\n", adapter->class);
+
-+ g) Mode of operation: Channel Priority
-+ At hardware level there are total 16 DMA pipes (i.e. 8 on each
-+ DMAC) each having its priority (i.e. pipe 0 having highest and 7 with
-+ lowest). but since the pipes are allocated dynamically you never know
-+ which pipe will be assigned to which channel. To take care of this
-+ issue driver has in-built channel priority policy manager
++ if (!(adapter->class & I2C_CLASS_HWMON))
++ {
++ stmems_perror("adapter class is not HWMON skip\n");
++ return 0;
++ }
+
-+ Priority DMAC0 PIPES DMAC1 PIPES Policy
-+ -----------------------------------------------------
-+ Highest | 0 | | 1 | HIGH
-+ . | 2 | | 3 | (0->15)
-+ . -----------------------------------------------------
-+ . | 4 | | 5 | NORMAL
-+ . | 6 | | 7 | (4->15)
-+ . -----------------------------------------------------
-+ . | 8 | | 9 | LOW
-+ . | 10 | | 11 | (8->15)
-+ . -----------------------------------------------------
-+ . | 12 | | 13 | UNDEFINED (fm 15->0)
-+ Lowest | 14 | | 15 | For MEM-To MEM Xfer (15->12)
-+ -----------------------------------------------------
++ err = i2c_probe(adapter, &addr_data, stmems_detect);
+
-+ Channel priority setup during configuration tells additional
-+ information to the driver that the channel under request has a
-+ particular priority. And the pipe allocation policy of a driver
-+ allocates a pipe accordingly for a transfer under schedule.
++ return err;
++}
+
-+ By default DMA_EXCH_PRIORITY_UNDEFINED is set for each channel, as
-+ per policy the free and available pipe search will be started from
-+ lowest to highest.
-+ there are three other priorities HIGH, NORMAL and LOW which can be set
-+ by ORing respective macro with other configuration parameters
+
-+ for ex. dma_info.mode=DMA_EXCH_PRIORITY_HIGH |
-+ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++/* This function is called by i2c_probe */
++static int stmems_detect(struct i2c_adapter *adapter, int address, int kind)
++{
++ struct i2c_client *new_client = NULL;
++ struct stmems_data *data = NULL;
++ int err = 0;
++ u8 temp_reg;
++ int ret;
+
-+ Channel priority setup macros for configurations-
-+ DMA_EXCH_PRIORITY_UNDEFINED
-+ DMA_EXCH_PRIORITY_LOW
-+ DMA_EXCH_PRIORITY_NORMAL
-+ DMA_EXCH_PRIORITY_HIGH
+
-+ h) Mode of operation: Queueing DMA transfer requests
-+ In the standard kernel DMA interface channel queueing is not allowed
-+ once enable_dma request is executed system discards all subsequent
-+ enable_dma request untill DMA finishes first scheduled request.
-+ Nomadik DMA driver provides you flexibility to enable and use this
-+ feature if required. Enabling this feature will accept all subsequent
-+ enable_dma requests and queue them in a pipe, as system finishes
-+ current transfer, next pre-scheduled transfer in a queue will be
-+ executed, thus all enable_dma requests can be processed.
++ stmems_pinfo("entered\n");
+
-+ This feature can be enabled by ORing a macro DMA_QUEUE_ENABLED with
-+ other configuration parameters
++ stmems_pinfo("kind: %d\n", kind);
++ stmems_pinfo("address: %d\n", address);
+
-+ for ex. dma_info.mode=DMA_QUEUE_ENABLED |
-+ FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++ {
++ stmems_perror("no SMBUS BYTE functionality detected\n");
++ goto error;
++ }
+
-+4. DMA Interrupt hanndling for callback functions.
-+======================================================
-+When you schedule a DMA transfer, there should be a mechanism by which you know
-+the transfer is finished sucessfully. In Nomadik DMA transfer a terminal
-+count interrupt will be generated at the end of sucessfull transfer which can
-+be requested and processed like any other standard interrupt.
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE))
++ {
++ stmems_perror("no SMBUS READ BYTE DATA functionality detected\n");
++ goto error;
++ }
+
-+There are S/w decoded IRQs associated with all DMA channels.
-+the macro IRQNO_FOR_DMACH(dmach) is provided to find irq for a DMA channel and
-+the macro DMACH_FOR_IRQNO(irq) can be used to find DMA channel for irq number
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA))
++ {
++ stmems_perror("no SMBUS READ BYTE functionality detected\n");
++ goto error;
++ }
+
-+The DMA callback functions can be invoked as interrupt handler and requested
-+through standard system calls i.e request_irq and free_irq.
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
++ {
++ stmems_perror("no SMBUS WRITE BYTE DATA functionality detected\n");
++ goto error;
++ }
+
-+It is recommented to use your own tasklets to do deffered processing
-+since it may block other DMA interuppts being processed in time.
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
++ {
++ stmems_perror("no SMBUS WRITE BYTE functionality detected\n");
++ goto error;
++ }
+
-+Below system messages indicates that irqno 188 to 191 are DMA interrupts
-+root@NDK10_A0:/home/prafulla/alsa# cat /proc/interrupts
-+ CPU0
-+ 4: 12077:PL02 - Nomadik Timer Tick
-+ 10: 0 - rtc
-+ 11: 0 - ssp
-+ 17: 581:PL08 - uart-pl011
-+ 19: 6:PL10 - msp
-+ 20: 33 - i2c0
-+ 21: 296 - i2c1
-+ 22: 81:PL02 - NMDK_MMC (data)
-+ 26: 1 - SAA0
-+ 27: 0 - SAA1
-+113: 0 - mmc_detect
-+168: 19176:PL08 - eth0
-+188: 46 dummy dmaclbk-sdmmc->mem
-+189: 0 dummy <NULL>
-+190: 10462 dummy dmaclbk-msp0rx->mem
-+191: 10437 dummy dmaclbk-mem->msp0tx
-+Err: 0
++ /* OK. For now, we presume we have a valid client. We now create the
++ client structure, even though we cannot fill it completely yet.
++ But it allows us to access stmems_{read,write}_value. */
++ data = kzalloc(sizeof(struct stmems_data), GFP_KERNEL);
++ if (!data) {
++ err = -ENOMEM;
++ goto error;
++ }
+
-+5. Scatter-gather Support
-+======================================================
-+The Nomadik DMA driver supprts scatter-gather transfer for MEM_TO_PERIPH and
-+PERIPH_TO_MEM type of data transfer. to use scatter gather suport following
-+sequence must be executed.
-+ a) request_dma, request_irq
-+ b) get the *sg and sg_len form the upper layers
-+ c) execute dma_map_sg with above information
-+ d) set peripharal DMA address (__set_dma_srcaddr / __set_dma_srcaddr)
-+ e) set memory DMA address using set_dma_sg API with sg information
-+ f) set_dma_count for transfer size
-+ g) execute enable_dma
-+ h) wait for transfer complete event through callback
-+ i) unmap sg list using dma_unmap_sg
-+ j) free_dma
++ memset(data, 0x00, sizeof(*data));
+
-+6. /proc/dma interfce.
-+======================================================
-+/proc/dma entry is created to show the information of allocated DMA resources
-+executing cat /proc/dma will list the allocation of all used DMA channles
++ new_client = &data->client;
++ i2c_set_clientdata(new_client, data);
++ new_client->addr = address;
++ new_client->adapter = adapter;
++ new_client->driver = &stmems_driver;
++ new_client->flags = 0;
+
-+for ex-
-+root@NDK10_A0:/home/prafulla/alsa# cat /proc/dma
-+ 0: DMACH: sdmmc->mem
-+ 1: DMACH: mem->sdmmc
-+ 2: DMACH: msp0rx->mem
-+ 3: DMACH: mem->msp0tx
++ /* Chip detection:
++ since the chip has a register that holds its hardware address,
++ we use that as an identification field. */
++ if (kind < 0){
++ temp_reg = stmems_read_value(new_client, MEMS_WHO_AM_I);
++ //if ( (int)temp_reg != address)
++ // goto free_error;
++ }
+
-+7. HOWTO add new DMA peripharal device support
-+======================================================
-+As per multiboard strategy
-+(ref : ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt)
-+for each supported SOC there is an arch/arm/mach-nomadik/<SOC>_devices.c
-+In this file there is data structure "dmadev_default_config_tbl"
-+Add a new entry for the table for new DMA peripharal device
-+(refer Architecture.DMA Support Chapter fo SOC specification)
++ /* Fill in the remaining client fields */
++ strncpy(new_client->name, "stmems", I2C_NAME_SIZE);
++ data->valid = 0;
++ mutex_init(&data->update_lock);
+
-+for ex-
-+ {.id = "sdmmc",
-+ .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD |
-+ DMA_BSIZE_8 | DMA_REQUEST_LINE(21) |
-+ DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE |
-+ DMA_DEV_DMAC1_CANBE_USED ),},
++ /* Tell the I2C layer a new client has arrived */
++ err = i2c_attach_client(new_client);
++ if (err)
++ goto error;
+
-+ explaination:
-+ id: This is the unique identification string will be used in
-+ configuration as srcdevtype or destdevtype.
-+ config: This should be ORed value of following selection
-+ a) DMA_AHB_M0 : to select AHB master 0 for this device
-+ or
-+ DMA_AHB_M1 : to select AHB master 1 for this device
++ /* Initialize the chip */
++ stmems_init_sensor(new_client);
+
-+ b) DMA_ADR_INC : to indicate DMA address is incremented after
-+ each transfer (memory, buffer case)
-+ or
-+ DMA_ADR_NOINC : to indicate DMA address is not incremented
-+ after each transfer (fifo case)
++ /* Register sysfs hooks */
++ data->class_dev = hwmon_device_register(&new_client->dev);
++ if (IS_ERR(data->class_dev)) {
++ err = PTR_ERR(data->class_dev);
++ goto detach_error;
++ }
+
-+ c) DMA_WIDTH_WORD : to select word(32bits) as transfer width
-+ or
-+ DMA_WIDTH_HALFWORD: to select halfword(16bits) as transfer width
-+ or
-+ DMA_WIDTH_BYTE : to select byte(8bits) as transfer width
-+
-+ d) DMA_BSIZE_1 : to indicate 1 byte makes one DMA brust
-+ or
-+ DMA_BSIZE_4 : to indicate 4 bytes makes one DMA brust
-+ or
-+ DMA_BSIZE_8 : to indicate 8 bytes makes one DMA brust
-+ or
-+ DMA_BSIZE_16 : to indicate 16 bytes makes one DMA brust
-+ or
-+ DMA_BSIZE_32 : to indicate 32 bytes makes one DMA brust
-+ or
-+ DMA_BSIZE_64 : to indicate 64 bytes makes one DMA brust
-+ or
-+ DMA_BSIZE_128 : to indicate 128 bytes makes one DMA brust
-+ or
-+ DMA_BSIZE_256 : to indicate 256 bytes makes one DMA brust
++ ret = device_create_file(&new_client->dev, &dev_attr_acc_x);
++ ret = device_create_file(&new_client->dev, &dev_attr_acc_y);
++ ret = device_create_file(&new_client->dev, &dev_attr_acc_z);
++ ret = device_create_file(&new_client->dev, &dev_attr_divisor);
++ ret = device_create_file(&new_client->dev, &dev_attr_fullscale);
++ ret = device_create_file(&new_client->dev, &dev_attr_BDU);
++ return 0;
+
-+ e) DMA_REQUEST_LINE(x) : program peripharal request line number
-+ (x less than 32)
++detach_error:
++ i2c_detach_client(new_client);
++//free_error:
++ kfree(data);
++error:
++ return err;
++}
+
-+ f) DMA_DEV_BSIZE_CONFIGURABLE: to indicate the burst size can be
-+ probrammed by user
-+ or
-+ DMA_DEV_BSIZE_NOT_CONFIGURABLE: to indicate the burst size can
-+ not be probrammed by user
-+ g) DMA_DEV_DWIDTH_CONFIGURABLE: to indicate the transfer width can
-+ be probrammed by user
-+ or
-+ DMA_DEV_DWIDTH_NOT_CONFIGURABLE: to indicate the transfer width
-+ can not be probrammed by user
++//TODO: powerdown
++static int stmems_detach_client(struct i2c_client *client)
++{
++ struct stmems_data *data = i2c_get_clientdata(client);
++ hwmon_device_unregister(data->class_dev);
++ i2c_detach_client(client);
++ kfree(data);
++ return 0;
++}
+
-+ h) DMA_DEV_DMAC1_CANBE_USED: to indicate DMA controller1 can be
-+ used for the transfer
-+ or
-+ DMA_DEV_DMAC0_CANBE_USED: to indicate DMA controller0 can be
-+ used for the transfer
-+ or
-+ DMA_DEV_BOTH_DMACS_CANBE_USED: to indicate both DMA controllers
-+ 0 and 1 can be used for the transfer
++/* Configure the chip, mainly with default values */
++static void stmems_init_sensor(struct i2c_client *client){
++ u8 conf_reg;
++ /* CTRL_REG1: enable axis, turn down powerdown mode, freq divisor 512 */
+
-+8. System Limitations and Solutions:
-+=====================================
-+1. MAX_DMA_CHANNELS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
-+ that defiens max no. of dma channels that can be used simultenously. if in
-+ complex system scenario these channels are insuffienent, you may increase
-+ this number as per your needs.
-+2. MAX_DMA_LLIS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
-+ that defiens max no. of LLIs used internally by dma driver. lli pool is
-+ internally maitained by driver and aquired whenver there is a enable_dma
-+ request and freed at each dma transfer completion. In a dynamic system
-+ usage a run time message "unable to find free lli.. rechecking..." can be
-+ observed, if such case you may increase the defined value for this macro,
-+ Assiging very large value eats free DMAble memory.
++ conf_reg = 0xC7;
+
-+==============================================================================
++ stmems_pinfo("entered\n");
+
++ stmems_write_value(client, MEMS_CTRL_REG1, conf_reg);
++ /* CTRL_REG2: fullscale 2g, batch update, big endian, disable INT,
++ 12bit right-justified, */
++ conf_reg = stmems_read_value(client, MEMS_CTRL_REG2);
++ conf_reg = 0x60;
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,53 @@
-+Filename: ./Documentation/arm/STM-Nomadik/faqs.txt
-+Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner: STMicroelectronics
-+Purpose:
-+ This documents describes frequesnty occuring problems and
-+ their brief solutions while using Nomadik-BSP
-+=============================================================================
++ stmems_write_value(client, MEMS_CTRL_REG2, conf_reg);
++ /* CTRL_REG3: disable interrupts generation, leave others values*/
++ conf_reg = stmems_read_value(client, MEMS_CTRL_REG3);
++ conf_reg &= 0x8F;
++ stmems_write_value(client, MEMS_CTRL_REG3, conf_reg);
++ return;
++}
+
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++static struct stmems_data *stmems_update_device(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct stmems_data *data = i2c_get_clientdata(client);
++ u8 status_reg;
+
-+F.A.Qs
-+======
-+Q: I am not getting console on CLCD even though CLCD is enabled
-+A: check your command line arguments, there should not be any console related
-+ configuration, in this case by default console will be configured to CLCD.
-+ In this case system will seek console input from standard input device.
++ stmems_pinfo("entered\n");
+
-+Q: NFS boot is giving messages "server not responding" very frequently
-+A: This may be due to network congestion, try NFS boot using "tcp" option
-+ (Ex. root=/dev/nfs nfsroot=<server_ipadr>:<mount_point_path>,tcp
-+ ip=<host_ipadr>:<server_ipadr>:<gateway_ipard>:255.255.255.0:<hostname>::
-+ console=ttyAMA1 mem=64M init=linuxrc)
++ mutex_lock(&data->update_lock);
++ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
++ status_reg = stmems_read_value(client, MEMS_STATUS_REG);
++ //TODO: we're assuming big endianess
++ //TODO: use 0x08 instead
++ if (status_reg & 0x01)
++ data->acc_x = stmems_join(stmems_read_value(client, MEMS_OUTX_H), stmems_read_value(client, MEMS_OUTX_L));
++ if (status_reg & 0x02)
++ data->acc_y = stmems_join(stmems_read_value(client, MEMS_OUTY_H), stmems_read_value(client, MEMS_OUTY_L));
++ if (status_reg & 0x04)
++ data->acc_z = stmems_join(stmems_read_value(client, MEMS_OUTZ_H), stmems_read_value(client, MEMS_OUTZ_L));
++ data->last_updated = jiffies;
++ data->valid = 1;
++ mutex_unlock(&data->update_lock);
+
-+Q. How to enable/Disable cursor on CLCD panel?
-+A. Create a dummy node "mknod /dev/dummy c 4 0 ".
-+ execute a command "echo -e "\033[?1c" > /dev/dummy" to disable the cursor
-+ and "echo -e "\033[?0c" > /dev/dummy" to enable the cursor
-+ You can also use the "setterm" program to control this and other aspects of
-+ the console. "setterm -cursor off > /dev/tty0" will do what you want.
-+ "man setterm" will give a vast list of stuff.
-+ There is more here:
-+ http://linux.bri.st.com/docs/manual/distribution/distribution_guide10.php
++ if (data)
++ {
++ stmems_pinfo("acc_x: %d\n", data->acc_x);
++ stmems_pinfo("acc_y: %d\n", data->acc_y);
++ stmems_pinfo("acc_z: %d\n", data->acc_z);
++ }
+
-+Q. How to disable CLCD screen blanking
-+A. Create a dummy node "mknod /dev/dummy c 4 0 ".
-+ Execute a command "echo -e "\033[9;0]" > /dev/dummy", this will set
-+ screen blanking interval to 0 and will not blank the screen at all.
++ return data;
++}
+
-+Q. Generally when the kernel is up and running, CLCD is active but after some
-+ time screen gets blanked, How to unblank the already blanked CLCD screen ?
-+A. Create a dummy node "mknod /dev/dummy c 4 0 ".
-+ Execute a command "echo -e "\033[13]" > /dev/dummy", this will activate
-+ CLCD screen.
++/* All registers are byte-sized */
++static inline u8 stmems_read_value(struct i2c_client *client, u8 reg)
++{
++ u8 temp;
+
-+Q. How to enable L2 Cache for Nomadik SOCs
-+A. Switch to kernel source path, execute "make menuconfig"
-+ Enable option "Enable L2 Cache controller" at location "x -> System Type"
-+ L2CC is not available on STn8810 SOC versions
++ stmems_pinfo("reading: 0x%02X\n", reg);
++ temp = i2c_smbus_read_byte_data(client, reg);
++ //nomadik_i2c_read_register(I2C_MEMS_CLIENT,&temp,reg,1);
++ stmems_pinfo("read: 0x%02X, value: 0x%02X\n", reg, temp);
+
-+==============================================================================
++ return temp;
++}
+
++static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value)
++{
++ stmems_pinfo("writing: 0x%02X, value: 0x%02X\n", reg, value);
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,140 @@
-+Filename: ./Documentation/arm/STM-Nomadik/gpio_user_guide.txt
-+Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner: STMicroelectronics
-+Purpose:
-+ This Users Guide explains GPIO implimentation and its usage
-+ from other drivers for Nomadik platforms
-+=============================================================================
++ return i2c_smbus_write_byte_data(client, reg, value);
++ //return nomadik_i2c_write_register(I2C_MEMS_CLIENT,&value,reg,1);
++}
+
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++static int __init stmems_init(void)
++{
++ stmems_pinfo("entered\n");
+
-+GPIO Configuration:
-+===================
-+By default GPIO driver is configured to link staticlly with kernel becasue
-+it is tightly coupled with irq.c. GPIO is necessary for Nomadik architecture
++ return i2c_add_driver(&stmems_driver);
++}
+
-+Brief Architecture:
-+GPIO dirver is registered as amba device and will be probed only if
-+matches peripharal ID, the SOC specific data and function iterface is provided
-+through platfrom_data pointer to allign driver code in sync with multiboard
-+strategy.
++static void __exit stmems_exit(void)
++{
++ stmems_pinfo("entered\n");
+
-+GPIO driver mainly provides two kinds of functionality
-+1. GPIO Interrupt hanndling and control.
-+2. Exported GPIO APIs
-+ 2.1 Usage of GPIO pins/block for read write APIs
-+ 2.2 Configuration for Alternate functions APIs
++ i2c_del_driver(&stmems_driver);
++}
+
-+1. GPIO Interrupt hanndling and control:-
-+==============================================
-+VIC generates a common interrupt for all 32 pins in a block, there are such
-+three to four blocks in a SOC, Each GPIO interrupt can be considered as
-+standard IRQ and can be processed through generic system call (please refer
-+irq_usrguide.txt). Further GPIO interrupts are softdecoded hence canot be
-+programmed as priority interrupts individually,
++static inline int stmems_join(u8 LSB, u8 MSB)
++{
++ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
++ if (MSB & 0x10)
++ MSB |= 0xE0;
++ return (s16)(LSB | ((MSB << 8)));
++}
+
-+2. Exported GPIO APIs
-+=====================
-+All exported GPIOs are protected against call before initialization. This
-+means if the GPIO driver cannot be probled due to any reasons and you try to
-+use GPIO exported APIs, and error will be returned.
-+APIS nomadik_gpio_readpin and nomadik_gpio_readblock are not protected against
-+interrupt configuration becasue reading a GPIO does not harm its usage from
-+other context. Where as all other APIS are protected against interrupt
-+cnfiguration. This means if the interrupt is already requested on a GPIO pin
-+the same pin cannot be configured untill you free that interrupt.
++MODULE_AUTHOR("Nicholas Angelo Crespi <roundtrip@gmail.com>");
++MODULE_DESCRIPTION("LIS3LV02DL MEMS three-axis accelerometer I2C driver");
++MODULE_VERSION(VERSION);
++MODULE_LICENSE("GPL");
+
-+2.1 Usage of GPIO pins/block for read write APIs
-+================================================
-+ a) nomadik_gpio_setpinconfig:
-+ Individual pin can be configured for desired operation.
-+ for ex.
-+ mmc_pin.dev_name = "test";
-+ mmc_pin.mode = GPIO_MODE_SOFTWARE;
-+ mmc_pin.direction = GPIO_DIR_OUTPUT;
-+ mmc_pin.debounce = GPIO_DEBOUNCE_ENABLE;
-+ mmc_pin.debounce_time = GPIO_DEBOUNCE_TIME_60_MICROSEC;
-+ ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++module_init(stmems_init);
++module_exit(stmems_exit);
+--- linux-2.6.20.orig/drivers/i2c/Kconfig
++++ linux-2.6.20/drivers/i2c/Kconfig
+@@ -32,10 +32,11 @@ config I2C_CHARDEV
+ contained in the file <file:Documentation/i2c/dev-interface>.
+
+ This support is also available as a module. If so, the module
+ will be called i2c-dev.
+
+
-+ The above code will configure GPIO_PIN_75 in GPIO mode used as output
-+ pin, enabled debouncing logic and set debounce time to 60 miroseconds.
-+ debounce logic will be enabled if supported by the SOC version.
-+ dev_name is a client device name to which the GPIO will be allocated.
-+
-+ b) nomadik_gpio_resetpinconfig:
-+ sets the particular pin to its reset state.
+ source drivers/i2c/algos/Kconfig
+ source drivers/i2c/busses/Kconfig
+ source drivers/i2c/chips/Kconfig
+
+ config I2C_DEBUG_CORE
+--- linux-2.6.20.orig/drivers/i2c/Makefile
++++ linux-2.6.20/drivers/i2c/Makefile
+@@ -1,11 +1,12 @@
+ #
+-# Makefile for the i2c core.
++# Makefile for the kernel i2c bus driver.
+ #
+
+ obj-$(CONFIG_I2C) += i2c-core.o
+ obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
+
-+ c) nomadik_gpio_writepin;
-+ write HIGN or LOW value on specified pin
+ obj-y += busses/ chips/ algos/
+
+ ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+--- linux-2.6.20.orig/drivers/i2c/busses/Kconfig
++++ linux-2.6.20/drivers/i2c/busses/Kconfig
+@@ -15,10 +15,20 @@ config I2C_ALI1535
+ Power Management Unit (PMU).
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-ali1535.
+
++config I2C_NOMADIK
++ tristate "I2C nomadik support"
++ depends on I2C
++ help
++ If you say yes to this option, support will be included for the i2c
++ controller on STn8810 .
++ This driver can also be built as a module. If so, the module
++ will be called nmdkmod_i2c.
+
-+ d) nomadik_gpio_readpin;
-+ reads HIGN or LOW value from specified pin
+
-+ e) nomadik_gpio_readblock;
-+ write multiple bits on specifed group of GPIOs
-+ ex.
-+ err = nomadik_gpio_writeblock(GPIO_BLOCK_32_BITS_64_TO_95,
-+ , 0x0000aa00, 0x0000fc00);
+ config I2C_ALI1563
+ tristate "ALI 1563"
+ depends on I2C && PCI && EXPERIMENTAL
+ help
+ If you say yes to this option, support will be included for the SMB
+--- linux-2.6.20.orig/drivers/i2c/busses/Makefile
++++ linux-2.6.20/drivers/i2c/busses/Makefile
+@@ -1,9 +1,26 @@
+ #
+ # Makefile for the i2c bus drivers.
+ #
+
++TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
++SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
++PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
+
-+ The above code writes HIGH on GPIO_PIN_74, LOW on GPIO_PIN_75,
-+ HIGH on GPIO_PIN_76, LOW on GPIO_PIN_77, and HIGN on GPIO_PIN_78
-+
-+ f) nomadik_gpio_writeblock;
-+ reads multiple bits on specifed group of GPIOs
++ifeq ($(CONFIG_NOMADIK_NDK10),y)
++EXTRA_CFLAGS := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__I2C_8810 -D__STN_8810
++endif
+
-+2.2 Configuration for Alternate functions APIs
-+================================================
-+ a) nomadik_gpio_altfuncenable:
-+ Sets the group of GPIOs dedicated for spefic alternate mode of
-+ operation.
++ifeq ($(CONFIG_NOMADIK_NDK15),y)
++EXTRA_CFLAGS := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10
++endif
+
-+ for ex.
-+ retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
-+
-+ The above code configures GPIOs 62 abd 63 (in case of stn8810) for
-+ altfun_A, the detailed information which pins to be configured in which
-+ mode for specified gpio_alt_function value(GPIO_ALT_I2C_0) is decided by
-+ the gpio_altfun_tbl[] declared in <SOC>_devices.c. It has table entries
-+ whcih controls altfun configuration.
++ifeq ($(CONFIG_NOMADIK_NHK15),y)
++EXTRA_CFLAGS := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10
++endif
+
-+ for example entry in table
-+ {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type =
-+ GPIO_ALTF_A,},
-+ states that- for gpio_alt_function value GPIO_ALT_I2C_0, from gpio pins 62
-+ to 63 needs to be configured for alternate function A. cont=0 specifies that
-+ there are no further pins to be configured for GPIO_ALT_I2C_0.
++obj-$(CONFIG_I2C_NOMADIK) += nmdkmod_i2c.o
+ obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o
+ obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o
+ obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o
+ obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
+ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
+@@ -48,5 +65,10 @@ obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
+ obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
+
+ ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
-+ example for cont=1
-+ {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type =
-+ GPIO_ALTF_A,},
-+ {.altfun = GPIO_ALT_SD_CARD,.start = 82,.end = 87,.cont = 1,.type =
-+ GPIO_ALTF_A,},
-+ {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type =
-+ GPIO_ALTF_A,},
-+
-+ In the above example cont=1 in first and second declaration states that there
-+ are additional entries in sequence to configure pins (82 to 87) and (14 to 16)
-+ in altfun A mode for the same gpio_alt_function value GPIO_ALT_MM_CARD
++nmdkmod_i2c-objs := i2c-nomadik.o
++nmdkmod_i2c-objs += i2c-$(SOC_NAME).o
+
-+ b) nomadik_gpio_altfuncdisable:
-+ This API reconfigures the group of GPIOs dedicated for specific
-+ alternate mode of operation in to GPIO mode.
+
-+Secured GPIO Access:
-+===================
-+To prevent GPIO resources getting used/altered by unauthorised way, a method
-+is provided to give secured control. When gpio is requested by setpinconfig,
-+you need to specify dev_name, GPIO driver records the information that the
-+particular pin is alloocated the client named "dev_name", while doing
-+resetpinconfig the same dev_id must be passed.
-+Simillarly the same should be followed while requesting enabling/disabling altfunction.
-+When the GPIO is requested for interrupt, the specified devname will be
-+configured as client name.
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c
+@@ -0,0 +1,1250 @@
+
-+/proc/gpio interface:
-+====================
-+/proc/gpio entry is created to show the information of allocated GPIO resources
++/* drivers/i2c/busses/i2c-nomadik.c
++ *
++ * Support for i2c bus on STn8800/8810/8815 (Nomadik) chips.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
+
-+=======================================================================================
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <linux/i2c-id.h>
++#include <asm/hardware.h>
++#include "i2c-nomadik.h"
++#include <asm/arch/gpio.h>
++#define DRIVER_VERSION "2.0.0"
++#define width 0
++#define BUSID 1
++#define error(format, arg...) printk( KERN_ERR "I2C: " format , ## arg)
++#define info(format, arg...)
++/*printk( KERN_INFO "I2C: %s " format, __func__, ## arg)*/
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,111 @@
-+Filename: ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
-+Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner: STMicroelectronics
-+Purpose:
-+ This HOWTO explains guidlines for addition of new Nomadik
-+ board support to the kernel source code
-+===============================================================================
++static unsigned int nomadik_i2c_func(struct i2c_adapter *adap);
++static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
++ struct i2c_msg msgs[], int num);
++static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
++ struct i2c_msg msgs[], int num);
+
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++/* Other variables indexed by bus */
++static struct nomadik_i2c_private i2c_driver[2];
+
-+Nomadik BSP kernel file naming conventions
-+============================================
-+It is strongly recommended to follow below filename conventions while adding
-+new board support for Nomadik
-+1. All the Nomadik architecture specific code must be in mach-nomadik and
-+ arch-nomadik folders in a kernel tree.
-+2. Generic and Nomadik specific device drives may be located into the respective
-+ folder in the kernel source tree (ex. nomadik keypad driver in
-+ drivers/input/keyboard/kpd-nomadik.c)
-+3. all Nomadik specific files in mach-nomadik and arch-nomadik folders should
-+ be named as <comp>.c/h
-+ (ex. gpio.h, msp.c)
-+4. all Nomadik platform specific files are named as <platform>_<purpose>.c/h
-+ (ex. ndk10_devices.c, ndk15_devices.h)
-+5. all Nomadik soc specific files are named as <soc>_<purpose>.c/h
-+ (ex. stn8810_devices.h, stn8815_devices.c)
++static struct i2c_algorithm nomadik_i2c_algo = {
++ master_xfer:nomadik_i2c_xfer,
++ smbus_xfer:NULL,
++ algo_control:NULL,
++ functionality:nomadik_i2c_func
++};
+
-+Important definations
-+==============================
-+1. target: It is a unique identity to describe supported board with a specific
-+ board version and specific SOC version.
-+ target is created by combination of board (i.e. platform) and
-+ Nomadik chip version (i.e. soc)
++static struct i2c_adapter nomadik_i2c[2] = { {
++ name: "i2c0",
++ id: I2C_ALGO_NOMADIK |
++ I2C_HW_NOMADIK,
++ algo: &nomadik_i2c_algo,
++ data: &i2c_driver[0],
++ class: I2C_CLASS_HWMON
+
-+2. platform: It is refered for board to be supported.
-+ One plaform may be supported by several targets
-+ One plaform may be supported by several socs
++ },
++{
++ name:"i2c1",
++ id:I2C_ALGO_NOMADIK | I2C_HW_NOMADIK,
++ algo:&nomadik_i2c_algo,
++ data:&i2c_driver[1],
++ }
++};
+
-+3. soc: It is refered for the Nomadik chip version to be suported.
-+ same soc may be supported on several platforms
++#if !defined (CONFIG_NOMADIK_NHK15)
++static struct i2c_client nomadik_i2c_clients[] = {
++ {
++ name:"motherboard",
++ id:I2C_MB_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_MB,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"ui db",
++ id:I2C_UI_DB_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_UI_DB,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"io expansion db1",
++ id:I2C_IO_EXP_DB1_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_IO_DB1,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"io expansion db2",
++ id:I2C_IO_EXP_DB2_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_IO_DB2,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"Matisse camera",
++ id:I2C_CIF_CAM_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_CIF_CAM,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"mem exp",
++ id:I2C_MEM_EXP_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_MEM_EXP,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"audio codec",
++ id:I2C_AUDIO_CODEC_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_AC,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"FM tuner",
++ id:I2C_FM_TUNER_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_FM_TUNER,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"Gas Gauge",
++ id:I2C_GAS_GAUGE_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_GAS_GAUGE,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"Matiise for litea cam",
++ id:I2C_LITEA_CAM_MOD_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_CAM_MOD,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"i2c0 loopback",
++ id:I2C0_LOOP_CLIENT,
++ flags:0,
++ addr:I2C0_LP_OWNADDR,
++ adapter:&nomadik_i2c[0]
++ },
++ {
++ name:"i2c1 loopback",
++ id:I2C1_LOOP_CLIENT,
++ flags:0,
++ addr:I2C1_LP_OWNADDR,
++ adapter:&nomadik_i2c[1]
++ },
++ {
++ name:"Pepperpot camera",
++ id:I2C_PP_CAM_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_PP_CAM,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {
++ name:"Touareg",
++ id:I2C_TOUAREG_CLIENT,
++ adapter:&nomadik_i2c[I2C_TOUAREG_ADAPTER],
++ flags:0,
++ addr:I2C_ADDR_TOUAREG,
++ }
+
-+Hence any Nomadik borad is identified as a "target" and supported by "soc"
-+ specific code and "platform" specific code well interfaced with generic
-+ code.
++};
++#else
++static struct i2c_client nomadik_i2c_clients[] = {
++ {//0x42
++ name:"Denc",
++ id:I2C_DENC_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_DENC,
++ adapter:&nomadik_i2c[0]
++ },
++ {//0x34
++ name:"audio codec",
++ id:I2C_AUDIO_CODEC_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_AC,
++ adapter:&nomadik_i2c[0]
++ },
++ {//0x20
++ name:"FM tuner",
++ id:I2C_FM_TUNER_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_FM_TUNER,
++ adapter:&nomadik_i2c[0]
++ },
++ {//FIXME
++ name:"Matiise for litea cam",
++ id:I2C_LITEA_CAM_MOD_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_CAM_MOD,
++ adapter:&nomadik_i2c[BUSID]
++ },
++ {//0x3A
++ name:"mems",
++ id:I2C_MEMS_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_MEMS,
++ adapter:&nomadik_i2c[0]
++ },
++ {//0x44, 0x46
++ name:"SIM card",
++ id:I2C_SIM_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_SIM,
++ adapter:&nomadik_i2c[0]
++ },
++ {//0x90
++ name:"touch screen",
++ id:I2C_TOUCH_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_TOUCH,
++ adapter:&nomadik_i2c[0]
++ },
++ {//0x86
++ name: "PEXP0",
++ id:I2C_STMPE0_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_STMPE0,
++ adapter:&nomadik_i2c[0],
++ },
++ {//0x88
++ name: "PEXP1",
++ id:I2C_STMPE1_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_STMPE1,
++ adapter:&nomadik_i2c[0],
++ },
++ {//0xE0
++ name:"Gas Gauge",
++ id:I2C_GAS_GAUGE_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_GAS_GAUGE,
++ adapter:&nomadik_i2c[0]
++ },
++ {//0x5A FIXME - MMC
++ name:"Power manager",
++ id:I2C_TOUAREG_CLIENT,
++ flags:0,
++ addr:I2C_ADDR_POWER,
++ adapter:&nomadik_i2c[0]
++ },
++ {
++ name:"i2c0 loopback",
++ id:I2C0_LOOP_CLIENT,
++ flags:0,
++ addr:I2C0_LP_OWNADDR,
++ adapter:&nomadik_i2c[0]
++ },
++ {
++ name:"i2c1 loopback",
++ id:I2C1_LOOP_CLIENT,
++ flags:0,
++ addr:I2C1_LP_OWNADDR,
++ adapter:&nomadik_i2c[1]
++ },
+
-+Device driver Support for Nomadik:
-+====================================
-+1. All the drivers suported on a target can be either SOC or platform specific
-+2. A platform specific code for all supported driver will be refered from a
-+ single file <platform_name>_devices.c through device specific interface.
-+3. A Nomadik chip specific code for all supported driver will be refered from a
-+ single file <soc_name>_devices.c through device specific interface.
-+4. Each device specific header file <pltfomr_name>_devices.h and
-+ <soc_name>_devices.h must be maintained to share a common hardware
-+ parameters across the drivers. Those two files are included in
-+ asm/arch/hardware.h which is further refered through asm/hardware.h
-+ Hence any kernel code seeking for hardware specific information (like
-+ base address, irqnos) can be made available by just including
-+ <asm/hardware.h>
-+5. Each header file described here should have relevent declaration related to
-+ the scope of its usage. ex. <platform_name>_devices.h should only have
-+ platforms specific declration.
++};
++#endif
+
-+Any Nomadik target can be supported by following set of files:-
-+ arch/arch/mach-nomadik/<soc_name>_devices.c
-+ inclue/asm-arm/arch-nomadik/<soc_name>_devices.h
-+ arch/arch/mach-nomadik/<platform_name>_devices.c
-+ inclue/asm-arm/arch-nomadik/<platform_name>_devices.h
++#if !defined(CONFIG_NOMADIK_NHK15)
+
-+But Generally, New board support will be added for already suported SOCs
-+hence, to add support for any new Nomadik target only three files need to be
-+added, those are:-
-+ arch/arch/mach-nomadik/<target_name>_Kconfig
-+ arch/arch/mach-nomadik/<platform_name>_devices.c
-+ inclue/asm-arm/arch0-nomadik/<platform_name>_devices.h
++/* This is an array of bus ids indexed by client id. They MUST be in the
++ sam order as the client structs above
++ */
++static __u32 nomadik_client_bus_id[] =
++ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, I2C_CLIENT_BUSID13 };
+
-+Steps to follow to add new target support for Nomadik
-+========================================================
-+1. Add ./arch/arm/mach-nomadik/<target_name>_Kconfig file for board
-+ configuration, <target_name> specified here will reflect as machine name.
++static struct nomadik_i2c_client priv_client[] = {
++ {
++ id:I2C_MB_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_MB,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_UI_DB_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_UI_DB,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_IO_EXP_DB1_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_IO_DB1,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_IO_EXP_DB2_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_IO_DB2,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_CIF_CAM_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_CIF_CAM,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C_MEM_EXP_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_MEM_EXP,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_AUDIO_CODEC_CLIENT,
++ bus_id:1,
++ addr:I2C_ADDR_AC,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C_FM_TUNER_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_FM_TUNER,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_GAS_GAUGE_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_GAS_GAUGE,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_LITEA_CAM_MOD_CLIENT,
++ bus_id:BUSID,
++ addr:I2C_ADDR_CAM_MOD,
++ endianness:LITTLE_END,
++ index_width:REG16},
++ {
++ id:I2C0_LOOP_CLIENT,
++ bus_id:0,
++ addr:I2C0_LP_OWNADDR,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C1_LOOP_CLIENT,
++ bus_id:1,
++ addr:I2C1_LP_OWNADDR,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_PP_CAM_CLIENT,
++ /* added for Pepperpot camera */
++ bus_id:1,
++ addr:I2C_ADDR_PP_CAM,
++ endianness:BIG_END,
++ index_width:REG16},
++ {
++ id:I2C_TOUAREG_CLIENT,
++ /* added for Touareg chip for power mgmt */
++ bus_id:I2C_TOUREG_CLIENT_BUSID,
++ addr:I2C_ADDR_TOUAREG,
++ endianness:LITTLE_END,
++ index_width:REG8
++#ifdef CONFIG_NOMADIK_NDK15
++ },
++ {
++ id:I2C_CPLD_CLIENT,
++ /* added for CPLD */
++ bus_id:I2C_CPLD_CLIENT_BUSID,
++ addr:I2C_ADDR_CPLD,
++ endianness:LITTLE_END,
++ /* check */
++ index_width:REG8
++#endif
++ },
++ {
++ id:I2C_DENC_CLIENT,
++ bus_id:1,
++ addr:I2C_ADDR_DENC,
++ endianness:LITTLE_END,
++ index_width:REG8}
+
-+ During make config/menuconfig arch/arm/mach-nomadik/Kconfig will be
-+ checked, and if is not found, it will be created automatically using
-+ all <target_name>_Kconfig files and Kconfig_nomadik file.
-+ 1. <target_name>_Kconfig file contain board specific configuration
-+ 2. Kconfig_nomadik contains generic configuration for all nomadik
-+ platforms
-+ for details refer provided ndk10_cut_a1_Kconfig file
++};
+
-+2. Add ./arch/arm/mach-nomadik/<platform_name>_devices.c file
-+ This file contains all the platfrom specific functions and data
-+ structures used by rest of the code. Any driver suported for Nomadik
-+ platform must access all the paramters through this file
-+ (for ex. base addres, irq number and other plaform specific data
-+ structures and function)
-+ It is recommended to refer such file for already suported platform
++#else
++/* This is an array of bus ids indexed by client id. They MUST be in the
++ sam order as the client structs above
++ */
++static __u32 nomadik_client_bus_id[] =
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 1};
+
-+3. Add ./include/asm-arm/arch-nomadik/<platform_name>_devices.h file
-+ This file must contain all the declarations for this platform
-+ which may be refered by the other drivers and kernel code.
-+ Note that this file is refered by some assembly code hence the
-+ content of this files must be maintained simple, standard and
-+ generic.
-+ It is recommended to refer such file for already suported platform
++static struct nomadik_i2c_client priv_client[] = {
++ {
++ id:I2C_DENC_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_DENC,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C_AUDIO_CODEC_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_AC,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C_FM_TUNER_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_FM_TUNER,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_LITEA_CAM_MOD_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_CAM_MOD,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_MEMS_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_MEMS,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C_SIM_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_SIM,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_TOUCH_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_TOUCH,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C_STMPE0_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_STMPE0,
++ endianness:LITTLE_END,
++ index_width:REG8
++ },
++ {
++ id:I2C_STMPE1_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_STMPE1,
++ endianness:LITTLE_END,
++ index_width:REG8
++ },
++ {
++ id:I2C_GAS_GAUGE_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_GAS_GAUGE,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C_TOUAREG_CLIENT,
++ bus_id:0,
++ addr:I2C_ADDR_POWER,
++ endianness:LITTLE_END,
++ index_width:REG8},
++ {
++ id:I2C0_LOOP_CLIENT,
++ bus_id:0,
++ addr:I2C0_LP_OWNADDR,
++ endianness:LITTLE_END,
++ index_width:0},
++ {
++ id:I2C1_LOOP_CLIENT,
++ bus_id:1,
++ addr:I2C1_LP_OWNADDR,
++ endianness:LITTLE_END,
++ index_width:0},
+
-+With the above addition/modification New target support will be available.
-+Select newly supported target in kernel configuration, build and execute
-+the code on new target
-+===============================================================================
++};
++#endif /*CONFIG_NOMADIK_NHK15*/
++static int i2c_initialize(struct nomadik_i2c_private *priv)
++{
++ /* Transfer configuration */
++ priv->config.freq_scl = STD_SPEED_IN_HZ;
++ priv->config.i2c_transmit_interrupt_threshold = 4;
++ priv->config.i2c_receive_interrupt_threshold = 4;
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,106 @@
-+This HOWTO esplains mounting the root file system via NFS on Nomadik Platform (nfsroot)
++ priv->config.bus_control_mode = I2C_BUS_MASTER_MODE;
++ priv->config.index_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
++ priv->config.data_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
+
-+As you know, all of us spend lot of time in-
-+1. Unzip/mount initrd to put the modules/application under test
-+2. Copying modules/applications to initrd
-+3. Unmount/gzip operation with initrd
-+4. Then load huge initrd and kernel each time to target board
-+ for execution.
++ /* Device configuration */
++ priv->config.freq_input = STD_F_IN_HZ;
+
-+So for each time even for a small change we need to repeat this process, and
-+downloading and system re-initialization eats lot of our development time.
-+Nfsroot is a good solution to overcome above issues.
++ if (priv->id)
++ priv->config.own_address = I2C1_LP_OWNADDR;
++ else
++ priv->config.own_address = I2C0_LP_OWNADDR;
+
-+Root file system can be mounted via NFS (nfsroot) on host and can be accessed
-+from your target machin.
++ if (setup_i2c_controller(priv) != 0) {
++ error("i2c device config 0 failed init\n");
++ return -EIO;
++ }
+
-+Advantages of this method are:-
-+===============================
-+1. No need to download ramdiks time to time (saves lot of time)
-+2. Since file system is on NFS, runtime results/logs dooes not vanishes
-+ in case of nomadik-system crash
-+3. Since file system is on NFS, it is transperant to host and target
-+4. Making, updating, mounting, unmounting, zipping, unzipping activities
-+ associated with ramdisk can be totally avoided (saves lot of time)
-+5. Offers comfortable and fast development environment
++ return 0;
++}
+
-+Host configuration to enable root NFS:-
-+========================================
-+1. Copy a "target" folder from toolchain at some fixed path on your Linux
-+ host
-+2. Switch to the dev folder of newly created target folder and create
-+ a node for console with command "mknod console c 5 1"
-+3. Then swtich to the target folder and create a symbolic link with
-+ command "ln -s /bin/busybox linuxrc
-+4. FTP and TFTP should be enabled on the host system. You can check the
-+ configuration by issuing the following command
++/**
++ * nomadik_i2c_get_info - Get status information of I2C controller
++ *
++ * @bus_id - The controller id.
++ * info - Info pointer describing the controller status.
++ *
++ * Return an info struct with current bus parameters.
++ **/
+
-+#> chkconfig --list | grep ftp
-+
-+Output should look like :-
-+vsftpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
-+ gssftp: off
-+ tftp: on
-+
-+Note: Method of enabling FTP can be different for different versions of Linux.
++int nomadik_i2c_get_info(__u32 bus_id, i2c_info_t * info)
++{
++ struct nomadik_i2c_private *priv;
++ priv = &i2c_driver[bus_id];
++ info->baseAddress = (__u32) priv->regs;
++ info->id = priv->id;
++ info->mode = priv->config.mode;
++ info->enabled = priv->config.enabled;
++ info->fSCL = priv->config.freq_scl;
++ info->fIn = priv->config.freq_input;
++ info->ownAddress = priv->config.own_address;
+
-+5. NFS should be enabled. Same can also be checked with the following
-+ command
++ return 0;
++}
+
-+#> chkconfig --list | grep nfs
++/**
++ * nomadik_get_client - Get client information
++ *
++ * @client_id - Client id for the I2C device.
++ *
++ * This function returns the address of the client struct identified by
++ * client_id
++ **/
+
-+Output should looklike
-+nfs 0:off 1:off 2:on 3:on 4:on 5:on 6:off
++struct i2c_client *nomadik_i2c_get_client(__u32 client_id)
++{
++ if ((client_id < 0) || (client_id >= I2C_NUM_CLIENTS)) {
++ error("error: nomadik get_client: client = %d\n", client_id);
++ return 0;
++ }
++ return &nomadik_i2c_clients[client_id];
++}
+
-+6. Also, check the entries of the /etc/xinetd.d/tftp file accordingly.
-+ In our case, it is :
++/**
++ * nomadik_i2c_is_busy - Check if the client is busy in an operation.
++ *
++ * @client_id - Identifier for the client whose status is required.
++ *
++ * This function checks the status of an event_type I2C_NO_EVENT. If this is
++ * the current active event, the controller is not busy, and the function
++ * returns false (0). If this is not the current event type, then the bus is
++ * in the process of doing something, so we return true -EBUSY. Note that there
++ * is no guarantee that the bus will not become busy between this call and
++ * a transfer request, so calls to the transfer functions should
++ * check the return - it will be -EBUSY if the bus is in use. -EINVAL
++ * is returned for an invalid client_id.
++ **/
+
-+service tftp
++int nomadik_i2c_is_busy(__u32 client_id)
+{
-+ disable = no
-+ socket_type = dgram
-+ protocol = udp
-+ wait = yes
-+ user = root
-+ server = /usr/sbin/in.tftpd
-+ server_args = -T 100000000 -v -c -s
-+/local_no_backup
-+# server_args = -s /tftpboot
-+ per_source = 11
-+ cps = 100 2
-+ flags = IPv4
++ int retval;
++
++ if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
++ return retval;
++
++ if (i2c_driver[nomadik_client_bus_id[client_id]].config.active_event.
++ type == I2C_NO_EVENT)
++ return 0;
++ return -EBUSY;
+}
+
-+7. Also make the entries in /etc/exports for the file systems that need
-+ to be shared. For options used, please refer the man pages of exports.
-+ In our case, it is :
++static irqreturn_t nomadik_i2c_irq_handler(int irq,
++ void *arg)
++{
++ __u32 id = ((struct nomadik_i2c_private *)arg)->id;
++ disable_irq(irq);
++ process_interrupt(&i2c_driver[id]);
+
-+/rtrt *(rw,insecure,no_root_squash,async)
-+/local_no_backup/target *(rw,insecure,no_root_squash,async)
++ enable_irq(i2c_driver[id].irq);
++ return IRQ_HANDLED;
++}
+
-+How to enable NFS feature in your development?
-+===============================================
-+1. Of cource you need to work on ethernet based environment
-+2. Enable ethernet driver in your kernel image
-+3. Enable following settings in your kernel image to enable nfsroot
-+a. Networking options --->IP: kernel level autoconfiguration
-+b. Networking options --->IP: BOOTP support
-+c. File systems --->Network File Systems --->NFS file system support
-+d. File systems --->Network File Systems --->Provide NFSv3 client support
-+e. File systems --->Network File Systems --->Root file system on NFS
-+4. Then compile kernel image, prepare uimage and download into the target
-+5. Set the command line arguments as -
++/**
++ * nomadik_i2c_wait_msg
++ *
++ * @nomadik_i2c_private - Private data for the controller
++ * @len - Amount of data in bytes to be transferred
++ *
++ * Poll until the event we've started is finished.
++ * Wait 1000 microseconds for each byte transferred.
++ * Here we have not used wait_event_interruptible_timeout()
++ * as this would cause a schedule in interrupt context in case I2C routines
++ * called by client drivers in interrupt handlers
++ *
++ * This function should be called ONLY by this driver.
++ **/
++#define WAIT_CONDITION (priv->config.active_event.type > I2C_NO_EVENT && priv->config.active_event.type <= I2C_BUS_ERROR_EVENT)
+
-+ "set bootargs root=/dev/nfs nfsroot=<HOST_IP_ADDR>:/<PATH>/ramdisk
-+ip=<TARGET_IP_ADDR>:<HOST_IP_ADDR>:<GATWAY_IP_ADDR_FOR_TARGET>:255.255.255.0:nomadik:: console=ttyAMA1 mac=<MAC_ADDRESS> init=linuxrc"
++static int nomadik_i2c_wait_msg(struct nomadik_i2c_private *priv, int len)
++{
++ if(wait_event_interruptible(priv->event_wq, WAIT_CONDITION))
++ return -EINVAL;
+
-+for example:-
-+"set bootargs root=/dev/nfs nfsroot=10.199.3.88:/local_no_backup/target
-+ip=10.199.32.165:10.199.3.88:10.199.32.254:255.255.255.0:NDK10_165::
-+mac=00:0D:88:45:5D:A5 console=ttyAMA1,115200n8 init=linuxrc"
++ return 0;
++}
+
-+6. And then boot the kernel with command "bootm 0x100000"
-+ (initrd address not needed since NFS)
++/**
++ * nomadik_i2c_xfer_byte - I2C transfer function used by nomadik_i2c_xfer to
++ * transfer a single byte
++ * @i2c_adapter - Adapter pointer to the controller
++ * @msgs[] - Pointer to data to be written.
++ * @num - Num messages
++ *
++ **/
+
-+Start enjoying the advantages of root NFS
++static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
++ struct i2c_msg msgs[], int num)
++{
++ int m, mm;
++ int status;
++ unsigned int addr;
++ struct nomadik_i2c_private *priv =
++ (struct nomadik_i2c_private *)i2c_adap->data;
++ __u32 bus_id = priv->id;
++ int read = 0;
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,171 @@
-+Filename: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
-+Author: Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner: STMicroelectronics
-+Created: 9th June 2007
++ if (msgs[0].len <= 0)
++ return 0;
+
-+Purpose:
-+This Users Guide explains interrupts implimentation and its usage from other
-+client drivers for Nomadik platforms
++ addr = msgs[0].addr;
+
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++ if (msgs[0].flags & I2C_M_TEN)
++ {
++ error("10 bit addressing not yet supported\n");
++ return -EINVAL;
++ }
+
-+Generic:
-+========
-+All the available interrupts can be used in through standard system calls
-+To use nomadik interrupts, include <linux/interrupt.h> ONLY in your code
-+Interrupt numbers generic to all Nomadik cuts are defined in irqs.h
-+Interrupt numbers specific to Nomadik cut is defined in <soc>_devices.h
-+(refer HOWTO-add_newboard.txt for more information)
++ if (down_interruptible(&nomadik_i2c[bus_id].lock))
++ return -ERESTARTSYS;
+
-+IRQ Description:
-+================
-+for stn8810 chip:
-+ IRQ0 to IRQ31 : IRQ lines provided by the VIC for different
-+ on-chip peripharals.
-+ IRQ32 to IRQ127 : IRQ lines for GPIO interrupts
-+
-+for stn8815 chip:
-+ IRQ0 to IRQ63 : IRQ lines provided by the VIC for different
-+ on-chip peripharals.
-+ IRQ64 to IRQ191 : IRQ lines for GPIO interrupts
-+
-+Specific:
-+========
-+1. Vectored Interrupt Controller (VIC) Interrupt Priority configuration:-
-+========================================================================
-+Generally whenever there is IRQ request to the VIC it will be processed
-+immediately, if two or more IRQs active at a time then first in a sequence
-+(i.e lower in number) will be processed first (this depends how you decode
-+irqnr in entry-macro.S).
++ for (m = 0; m < num; m++)
++ {
++ info("message: %d, addr: %d\n", m, msgs[m].addr);
++ info("message: %d, flags: %d\n", m, msgs[m].flags);
++ info("message: %d, len: %d\n", m, msgs[m].len);
+
-+Vectored interrupt processing hardware on Nomadik SOC is used to detect,
-+process and service the interrupts in prioritized manner.
-+This provides faster interrupt processing for comples decision.
-+This adds more flexibility to the system and to the driver developers to
-+take complex decision making about which interrupt to be proceesed first
-+when more than one IRQ goes active at a time.
++ for(mm = 0; mm < msgs[m].len; mm++)
++ info("message: %d, buf[%d]: 0x%02X\n", m, mm, msgs[m].buf[mm]);
+
-+also while processing priority interrupt all lower priority interrupts will
-+be disabled by hardware whereas all higher priority interrupts will be active.
-+This adds a benefit to use SA_IRQPRIORITY_x over SA_INTERRUPT becasue
-+SA_INTERRUPT disables all interrupt while processign it.
++ info("message: %d, bus id: 0x%02X\n", m, bus_id);
++ }
+
-+Any 15 (maximum) IRQs lines of VIC can be programmed for priority,
-+GPIO_IRQs cannot be programmed for priority since the are softdecoded.
++#if !defined(CONFIG_NOMADIK_NHK15)
++ reset_i2c(priv);
++#endif
+
-+How to program a interrupt for desired priority?
-+================================================
-+this can be done in two ways
-+a. using request_irq
-+ for ex.
-+ err = request_irq(IRQ_UART1, test_inthandle, SA_IRQPRIORITY_4,
-+ "test", test_data);
++ /* Save parameters. */
++ priv->config.slave_address = addr;
++ priv->config.status = I2C_STATUS_SLAVE_MODE;
++ priv->config.index_format = I2C_BYTE_INDEX;
++ priv->config.active_event.type = I2C_NO_EVENT;
++ priv->config.multi_operation = NOMADIK_TRUE;
+
-+ will request IRQ with interrupt priority level 4
++ if (i2c_initialize(priv)) {
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
+
-+b) using set_irq_type
-+ This call can be used any time after requesting a interrupt to
-+ to enable/disable/change priority level for specific IRQ line
++ if (verify_parameters(priv))
++ {
++ error("Error in parameters\n");
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
+
-+ For ex.
-+ set_irq_type(IRQ_UART1, SA_IRQPRIORITY_10);
++ if (num > 1)
++ {
++ if (msgs[1].flags & I2C_M_RD)
++ {
++ read = 1;
++ }
++ }
+
-+ will enable priority level for pre-requested IRQ
-+ if IRQ was requested with different priority level earlier,
-+ this call will change it to specified level
++ if (read != 0)
++ {
+
-+How to disable interrupt priority for a IRQ?
-+===========================================
-+a) using set_irq_type api
-+ This call can be used any time after requesting a interrupt to
-+ to enable/disable/change priority level for specific IRQ line
++ /* Save parameters. */
++ priv->config.databuffer = &(msgs[1].buf[0]);
++ priv->config.count_data = msgs[1].len;
++ priv->config.register_index = msgs[0].buf[0];
++ /* Do the read */
++ priv->config.operation = I2C_READ;
+
-+ For ex.
-+ set_irq_type(IRQ_UART1, SA_IRQPRIORITY_DISABLE);
++ status = read_i2c(priv);
+
-+ will disable priority level for pre-requested IRQ and will configure
-+ if as normal IRQ
++ if (status)
++ {
++ error("Error in read_register: %d\n", status);
++ up(&nomadik_i2c[bus_id].lock);
++ return status;
++ }
++ else if (status == 0)
++ {
+
-+How to know which IRQs are programmed for priority?
-+===================================================
-+executing cat /proc/interrupts interface will display all interrupt information
-+if any IRQ is programmed with some priority then it will reflect as-
++ if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
++ {
++ status = nomadik_i2c_wait_msg(priv, msgs[0].len);
++ if (status)
++ {
++ error("Message timeout with no handled event\n");
++ error("error waiting for i2c read: %d\n", status);
++ up(&nomadik_i2c[bus_id].lock);
++ return status;
++ }
++ }
++ }
+
-+# cat /proc/interrupts
-+ CPU0
-+ 4: 143193 Nomadik Timer Tick
-+ 10: 0 rtc
-+ 11: 0 ssp
-+ 13: 1 dma1
-+ 15: 0 dma0
-+ 17: 745 uart-pl011
-+ 20: 0 i2c0
-+ 21: 4 i2c1
-+ 22: 132 NMDK_MMC (data)
-+ 30: 0:PL07 msp1
-+ 31: 0 msp2
-+ 72: 122 nmdk-kp
-+ 77: 433 eth0
-+ 79: 5175 nmdk-tp
-+ 81: 32 mmc_detect
-+Err: 0
-+#
++ info("ret message: 0, buf[0]: 0x%02X\n", msgs[0].buf[0]);
++ info("ret message: 1, buf[0]: 0x%02X\n", msgs[1].buf[0]);
+
-+Above message indicates that IRQ30 for msp1 is programmed as priority interrupt
-+with level 7.
++ mdelay(1);
++ priv->config.active_event.type = I2C_NO_EVENT;
+
-+2. GPIO Interrupt hanndling and control:-
-+==============================================
-+GPIO Interrupt control is handled through standard system calls. The macros
-+(IRQNO_GPIO(x) and GPIO_PIN_FOR_IRQ(x)) are provided to find out interrupt
-+number associated with GPIO and vice-versa.
-+Following system calls are suported for GPIO interrupt control:-
-+a) request_irq/ free_irq:
-+ works in a standard way to request and free GPIO interrupt.
-+ When request_irq is invoked for GPIO, it first configures GPIO pin
-+ for input operation with debounce disable (if supported). Then it sets
-+ interrupt type for falling edge detection by default if not specified
-+ in interrupt_flags. You can set type of interrupt during request by
-+ passing required SA_TTRIGGER_ flags. GPIO interrupt type will be set
-+ during request_irq call if the requested interrupt is NOT shared.
-+
-+ for ex.
-+ err = request_irq(IRQNO_GPIO(x), test_inthandle, SA_TRIGGER_RISING,
-+ "test", test_data);
++ up(&nomadik_i2c[bus_id].lock);
++ }
++ else
++ {
++ /* Save parameters. */
++ priv->config.databuffer = &(msgs[0].buf[1]);
++ priv->config.count_data = 1;
++ priv->config.register_index = msgs[0].buf[0];
+
-+ will request rising edge interrupt for GPIO x
-+
-+b) enable_irq/disable_irq:
-+ These are standard system calls can be used to enable or disable GPIO
-+ irqs whenever required.
-+
-+ for ex.
-+ enable_irq(IRQNO_GPIO(x));
++ /* Do the write */
++ priv->config.operation = I2C_WRITE;
++ status = write_i2c(priv);
++ if (status)
++ {
++ error("Error in write_register: %d\n", status);
++ up(&nomadik_i2c[bus_id].lock);
++ return status;
++ }
++ else if (status == 0)
++ {
++ if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
++ {
++ status = nomadik_i2c_wait_msg(priv, msgs[0].len - 1);
++ if (status)
++ {
++ error("Message timeout with no handled event\n");
++ error("error waiting for i2c write: %d\n", status);
++ up(&nomadik_i2c[bus_id].lock);
++ return status;
++ }
++ }
++ }
++ mdelay(1);
++ priv->config.active_event.type = I2C_NO_EVENT;
++ up(&nomadik_i2c[bus_id].lock);
++ }
+
-+ will enable interrupt for GPIO x
++ return 0;
+
-+c) set_irq_type:
-+ By defult interrupt is requested as falling edge through request_irq call.
-+ If you want to use other type of interrupt detection, this call can be used.
-+ This call will be necessary to configure shared GPIO interrupt
++}
+
-+ For ex.
-+ set_irq_type(IRQNO_GPIO(x), SA_TRIGGER_LOW);
-+ sets irq type as low level detection
++/**
++ * nomadik_i2c_xfer - I2C transfer function used by kernel framework
++ * @i2c_adapter - Adapter pointer to the controller
++ * @msgs[] - Pointer to data to be written.
++ * @num - Amount of data in bytes to be written
++ *
++ * This is the function called by the generic kernel i2c API calls. Note that
++ * this code is protected by the semaphore set in the kernel i2c_transfer()
++ * function.
++ * Retrive the client specific information from the client id and feed it to
++ * the controller specific configuration. Then call the respective board
++ * specific routine.
++ **/
+
-+ set_irq_type(IRQNO_GPIO(x), (SA_TRIGGER_RISING|SA_TRIGGER_FALLING);
-+ sets irq type for both edges detection
++static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
++ struct i2c_msg msgs[], int num)
++{
++ int i;
++ int status;
++ unsigned int addr;
++ struct nomadik_i2c_private *priv =
++ (struct nomadik_i2c_private *)i2c_adap->data;
++ __u32 bus_id = priv->id;
++ /*read byte or write byte, SMBus emulated (see i2c_smbus_xfer_emulated)*/
++ if ((num == 2 && msgs[0].len == 1 && msgs[1].len == 1 && (msgs[1].flags & I2C_M_RD)) ||
++ (num == 1 && msgs[0].len == 2 && ((msgs[0].flags & I2C_M_RD) == 0)))
++ {
++ return nomadik_i2c_xfer_byte(i2c_adap, msgs, num);
++ }
+
-+ Please note that set_irq_type overwites previous irq_type, hence the GPIO
-+ interrupt behaviour depends upon where you call this API.
-+
-+ for ex. if you set_irq_type first and then requested interrupt, the
-+ request_irq will overwrite the previously set irq type and vice versa.
++ for (i = 0; i < num; i++) { /* deal with message i */
++ if (msgs[i].len > 0) { /*sanity check - message length */
++ /*prepare address */
++ addr = msgs[i].addr;
++ if (msgs[i].flags & I2C_M_RD)
++ addr |= 0x1;
+
-+d) enable_irq_wake/disable_irq_wake:
-+ the frame work is provided to handle these call for GPIO interrupt to
-+ enable/disable wakup event generation to the power management unit.
++ if (msgs[i].flags & I2C_M_TEN) {
++ error("10 bit addressing not yet supported\n");
++ return -EINVAL;
++ }
+
-+===============================================================================
++ if (down_interruptible(&nomadik_i2c[bus_id].lock))
++ return -ERESTARTSYS;
+
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,122 @@
-+
-+ * 1 Nomadik Power Management Strategy
-+ * ==========================================
-+ * Power in nomadik can be saved by following features
-+ * 1. Enable idle tick suppression or dynamic tick
-+ * 2. Frequency scaling
-+ * 3. Voltage scaling
-+ * 4. Take system into soft sleep
-+ * 5. Take system into deep sleep
-+ * 6. Taking individual device (eg. CLCD) into suspend state
-+ *
-+ *
-+ * 1.1 How to Enable idle tick suppression or dynamic tick
-+ * =========================================================
-+ *
-+ * 1. Select CONFIG_NO_IDLE_HZ in kernel features in kernel configuration
-+ * 2. To enable dynamic tick
-+ * echo -n 1 > /sys/devices/system/timer/timer0/dyn_tick
-+ * 3. Dynamic tick can be disabled by
-+ * echo -n 0 > /sys/devices/system/timer/timer0/dyn_tick
-+ * 4. In idle thread, arm put itself in WFI, hence power is saved. By using
-+ * dynamic tick we can put ARM in WFI for longer duration
-+ *
-+ * 1.2 Scaling frequencies
-+ *====================================
-+ * 1. Select CONFIG_CPU_FREQ & CONFIG_CPU_FREQ_NOMADIK in kernel configuration
-+ * during compilation
-+ * 2. Check current frequency (In Khz) by
-+ * cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
-+ * 3. Change system freq by
-+ * echo -n <freq in khz > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
-+ * If entered freq is not supported in system then next higher valid
-+ * frequency is set
-+ * 4. For frequencies which require voltage change, new voltage will be
-+ * reflected. It can be checked by voltage sysfs file
-+ * 5. If mapping for frequency and voltage is changed then change is required
-+ * in arch/arm/mach-nomadik/power.c
-+ * 6. If different SDRAM parameters are to be changed then change is required
-+ * in arch/arm/mach-nomadik/power.c
-+ * 7. If frequencies are to be altered then change is required in arch/arm/mach-nomadik/power.c
-+ *
-+ *
-+ * 1.3 Scaling Voltage
-+ *====================================
-+ * 1. To enable voltage scaling either CONFIG_CPU_FREQ or CONFIG_PM_NOMADIK
-+ * must be selected in configuration
-+ * 2. Current voltage can be checked by
-+ * cat /sys/nomadik/current_voltage
-+ * VOLTAGE will be shown in milli volt
-+ * 3. To change in current voltage without changing frequency use
-+ * echo < voltage in milli volt > > current_voltage
-+ * However directly changing voltage without frequency is not recommended
-+ * but can be used for performance/testing purpose.
-+ * 4. If voltages are to be altered then change is required in arch/arm/mach-nomadik/power.c
-+ *
-+ *
-+ * 1.4 Taking system into soft sleep
-+ *====================================
-+ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
-+ * 2. Change required sleep type to softsleep by
-+ * echo -n softsleep > /sys/nomadik/sleep_type
-+ * 3. To take system into sleep use
-+ * echo -n mem > /sys/power/state
-+ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
-+ * 5. To specify rtc wakeup duration ( sleeping time )
-+ echo -n <sleep duration in seconds > >sleep_duration
-+ Default sleep duratioon is 15 seconds
-+ * 6. To take system directly into soft sleep without linux power management
-+ * framework use
-+ * echo 1 > /sys/nomadik/softsleep_enable
-+ * This is to be used when we are sure that no driver is active i.e.
-+ * driver need not be be suspended. This interface can save transition
-+ * time but is not recommended. It can be used for testing purpose.
-+ *
-+ *
-+ * 1.5 Taking system into deep sleep
-+ *====================================
-+ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
-+ * 2. Change required sleep type to deepsleep by
-+ * echo -n deepsleep > /sys/nomadik/sleep_type
-+ * 3. To take system into sleep use
-+ * echo -n mem > /sys/power/state
-+ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
-+ * 5. To specify rtc wakeup duration ( sleeping time )
-+ * echo -n <sleep duration in seconds > >sleep_duration
-+ * Default sleep duration is 15 seconds
-+ *
-+ * 1.6 Taking Individual device into suspend/resume state
-+ *=======================================================
-+ * 1. Individual device can be taken into suspended state by writing into sysfs
-+ * file. Similiarly device can be resumed back
-+ * 2. For example to take CLCD into suspend state use
-+ echo -n 2 > /sys/devices/mb:c0/power/state
-+ * 3. For example to take CLCD into resumed state use
-+ echo -n 0 > /sys/devices/mb:c0/power/state
-+ * 4. Similar things can be done for other devices. Few devices such as RTC,
-+ * GPIO should not be takne into suspend state by this interface.
-+ *
-+ *
-+ * 1.7 Enabling/Disabling Individual devices(Keypad, Touchpanel, MMC) as wakeup devices
-+ *===================================================================================
-+ * 1. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
-+ * echo enabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
-+ * 2. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
-+ * echo disabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
-+ * If a device's wakeup state is disabled, it cannot be used for waking the
-+ * system from sleep.
-+ * 3. Above steps are applicable for any device that can wakeup the system
-+ *
-+ *
-+ * 1.8 To add a device that can be used to wakeup
-+ *================================================
-+ * 1. To make a platform device to be able to wakeup a system, change is
-+ * required in board specific file like arch/arm/mach-nomadik/ndk15_devices.c
-+ * 2. To make a amba device to be able to wakeup a system, change is required
-+ * in platform specific file like arch/arm/mach-nomadik/stn8815_devices.c
-+ *
-+ *
-+ *
-+ */
++ reset_i2c(priv);
+
++ /* Save parameters. */
++ priv->config.slave_address = addr;
++ priv->config.status = I2C_STATUS_SLAVE_MODE;
++ priv->config.index_format = I2C_NO_INDEX;
++ priv->config.databuffer = msgs[i].buf;
++ priv->config.count_data = msgs[i].len;
++ priv->config.multi_operation = NOMADIK_TRUE;
+
-diff -Nauprw linux-2.6.20/Documentation/DocBook/kgdb.tmpl ../new/linux-2.6.20/Documentation/DocBook/kgdb.tmpl
---- linux-2.6.20/Documentation/DocBook/kgdb.tmpl 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/DocBook/kgdb.tmpl 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,234 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
++ if (i2c_initialize(priv)) {
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
+
-+<book id="kgdbInternals">
-+ <bookinfo>
-+ <title>KGDB Internals</title>
++ if (verify_parameters(priv)) {
++ error("Error in parameters\n");
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
+
-+ <authorgroup>
-+ <author>
-+ <firstname>Tom</firstname>
-+ <surname>Rini</surname>
-+ <affiliation>
-+ <address>
-+ <email>trini@kernel.crashing.org</email>
-+ </address>
-+ </affiliation>
-+ </author>
-+ </authorgroup>
++ if (addr & 1) {
++ /* Do the read */
++ priv->config.operation = I2C_READ;
++ /* read */
++ status = read_i2c(priv);
++ if (status) {
++ error("Error in read_register: %d\n",
++ status);
++ up(&nomadik_i2c[bus_id].lock);
++ return status;
++ } else if (status == 0) {
+
-+ <authorgroup>
-+ <author>
-+ <firstname>Amit S.</firstname>
-+ <surname>Kale</surname>
-+ <affiliation>
-+ <address>
-+ <email>amitkale@linsyssoft.com</email>
-+ </address>
-+ </affiliation>
-+ </author>
-+ </authorgroup>
++ if (priv->config.data_transfer_mode !=
++ I2C_TRANSFER_MODE_POLLING) {
++ status =
++ nomadik_i2c_wait_msg(priv,
++ msgs
++ [i].
++ len);
++ if (status) {
++ error
++ ("Message timeout with no handled event\n");
++ error
++ ("error waiting for i2c read: %d\n",
++ status);
++ up(&nomadik_i2c[bus_id].
++ lock);
++ return status;
++ }
++ }
++ }
++ /* mdelay(1); */ /* NM */
++ priv->config.active_event.type = I2C_NO_EVENT;
++ up(&nomadik_i2c[bus_id].lock);
+
-+ <copyright>
-+ <year>2004-2005</year>
-+ <holder>MontaVista Software, Inc.</holder>
-+ </copyright>
-+ <copyright>
-+ <year>2004</year>
-+ <holder>Amit S. Kale</holder>
-+ </copyright>
++ } else {
++ /* Do the write */
++ priv->config.operation = I2C_WRITE;
++ status = write_i2c(priv);
++ if (status) {
++ error("Error in write_register: %d\n",
++ status);
++ up(&nomadik_i2c[bus_id].lock);
++ return status;
++ } else if (status == 0) {
+
-+ <legalnotice>
-+ <para>
-+ This file is licensed under the terms of the GNU General Public License
-+ version 2. This program is licensed "as is" without any warranty of any
-+ kind, whether express or implied.
-+ </para>
++ if (priv->config.data_transfer_mode !=
++ I2C_TRANSFER_MODE_POLLING) {
++ status =
++ nomadik_i2c_wait_msg(priv,
++ msgs
++ [i].
++ len);
++ if (status) {
++ error
++ ("Message timeout with no handled event\n");
++ error
++ ("error waiting for i2c write: %d\n",
++ status);
++ up(&nomadik_i2c[bus_id].
++ lock);
++ return status;
++ }
++ }
++ }
++ /* mdelay(1); */ /* NM */
++ priv->config.active_event.type = I2C_NO_EVENT;
++ up(&nomadik_i2c[bus_id].lock);
++ }
+
-+ </legalnotice>
-+ </bookinfo>
++ }
++ }
++ return 0;
++}
+
-+<toc></toc>
-+ <chapter id="Introduction">
-+ <title>Introduction</title>
-+ <para>
-+ kgdb is a source level debugger for linux kernel. It is used along
-+ with gdb to debug a linux kernel. Kernel developers can debug a kernel
-+ similar to application programs with the use of kgdb. It makes it
-+ possible to place breakpoints in kernel code, step through the code
-+ and observe variables.
-+ </para>
-+ <para>
-+ Two machines are required for using kgdb. One of these machines is a
-+ development machine and the other is a test machine. The machines are
-+ typically connected through a serial line, a null-modem cable which
-+ connects their serial ports. It is also possible however, to use an
-+ ethernet connection between the machines. The kernel to be debugged
-+ runs on the test machine. gdb runs on the development machine. The
-+ serial line or ethernet connection is used by gdb to communicate to
-+ the kernel being debugged.
-+ </para>
-+ </chapter>
-+ <chapter id="CompilingAKernel">
-+ <title>Compiling a kernel</title>
-+ <para>
-+ To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
-+ and then select "KGDB: kernel debugging with remote gdb".
-+ </para>
-+ <para>
-+ The first choice for I/O is <symbol>CONFIG_KGDB_ONLY_MODULES</symbol>.
-+ This means that you will only be able to use KGDB after loading a
-+ kernel module that defines how you want to be able to talk with
-+ KGDB. There are two other choices (more on some architectures) that
-+ can be enabled as modules later, if not picked here.
-+ </para>
-+ <para>The first of these is <symbol>CONFIG_KGDB_8250_NOMODULE</symbol>.
-+ This has sub-options such as <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol>
-+ which toggles choosing the serial port by ttyS number or by specifying
-+ a port and IRQ number.
-+ </para>
-+ <para>
-+ The second of these choices on most systems for I/O is
-+ <symbol>CONFIG_KGDBOE</symbol>. This requires that the machine to be
-+ debugged has an ethernet card which supports the netpoll API, such as
-+ the cards supported by <symbol>CONFIG_E100</symbol>. There are no
-+ sub-options for this, but a kernel command line option is required.
-+ </para>
-+ </chapter>
-+ <chapter id="BootingTheKernel">
-+ <title>Booting the kernel</title>
-+ <para>
-+ The Kernel command line option <constant>kgdbwait</constant> makes kgdb
-+ wait for gdb connection during booting of a kernel. If the
-+ <symbol>CONFIG_KGDB_8250</symbol> driver is used (or if applicable,
-+ another serial driver) this breakpoint will happen very early on, before
-+ console output. If you wish to change serial port information and you
-+ have enabled both <symbol>CONFIG_KGDB_8250</symbol> and
-+ <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> then you must pass the option
-+ <constant>kgdb8250=<io or mmio>,<address>,<baud
-+ rate>,<irq></constant> before <constant>kgdbwait</constant>.
-+ The values <constant>io</constant> or <constant>mmio</constant> refer to
-+ if the address being passed next needs to be memory mapped
-+ (<constant>mmio</constant>) or not. The <constant>address</constant> must
-+ be passed in hex and is the hardware address and will be remapped if
-+ passed as <constant>mmio</constant>. The value
-+ <constant>baud rate</constant> and <constant>irq</constant> are base-10.
-+ The supported values for <constant>baud rate</constant> are
-+ <constant>9600</constant>, <constant>19200</constant>,
-+ <constant>38400</constant>, <constant>57600</constant>, and
-+ <constant>115200</constant>.
-+ </para>
-+ <para>
-+ To have KGDB stop the kernel and wait, with the compiled values for the
-+ serial driver, pass in: <constant>kgdbwait</constant>.
-+ </para>
-+ <para>
-+ To specify the values of the serial port at boot:
-+ <constant>kgdb8250=io,3f8,115200,3</constant>.
-+ On IA64 this could also be:
-+ <constant>kgdb8250=mmio,0xff5e0000,115200,74</constant>
-+ And to have KGDB also stop the kernel and wait for GDB to connect, pass in
-+ <constant>kgdbwait</constant> after this arguement.
-+ </para>
-+ <para>
-+ To configure the <symbol>CONFIG_KGDBOE</symbol> driver, pass in
-+ <constant>kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]</constant>
-+ where:
-+ <itemizedlist>
-+ <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem>
-+ <listitem><para>src-ip: source IP to use (interface address)</para></listitem>
-+ <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem>
-+ <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem>
-+ <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem>
-+ <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem>
-+ </itemizedlist>
-+ </para>
-+ <para>
-+ The <symbol>CONFIG_KGDBOE</symbol> driver can be reconfigured at run
-+ time, if <symbol>CONFIG_SYSFS</symbol> and
-+ <symbol>CONFIG_MODULES</symbol> by echo'ing a new config string to
-+ <constant>/sys/module/kgdboe/parameter/kgdboe</constant>. The
-+ driver can be unconfigured with the special string
-+ <constant>not_configured</constant>.
-+ </para>
-+ </chapter>
-+ <chapter id="ConnectingGDB">
-+ <title>Connecting gdb</title>
-+ <para>
-+ If you have used any of the methods to have KGDB stop and create
-+ an initial breakpoint described in the previous chapter, kgdb prints
-+ the message "Waiting for connection from remote gdb..." on the console
-+ and waits for connection from gdb. At this point you connect gdb to kgdb.
-+ </para>
-+ <para>
-+ Example (serial):
-+ </para>
-+ <programlisting>
-+ % gdb ./vmlinux
-+ (gdb) set remotebaud 115200
-+ (gdb) target remote /dev/ttyS0
-+ </programlisting>
-+ <para>
-+ Example (ethernet):
-+ </para>
-+ <programlisting>
-+ % gdb ./vmlinux
-+ (gdb) target remote udp:192.168.2.2:6443
-+ </programlisting>
-+ <para>
-+ Once connected, you can debug a kernel the way you would debug an
-+ application program.
-+ </para>
-+ </chapter>
-+ <chapter id="CommonBackEndReq">
-+ <title>The common backend (required)</title>
-+ <para>
-+ There are a few flags which must be set on every architecture in
-+ their <asm/kgdb.h> file. These are:
-+ <itemizedlist>
-+ <listitem>
-+ <para>
-+ NUMREGBYTES: The size in bytes of all of the registers, so
-+ that we can ensure they will all fit into a packet.
-+ </para>
-+ <para>
-+ BUFMAX: The size in bytes of the buffer GDB will read into.
-+ This must be larger than NUMREGBYTES.
-+ </para>
-+ <para>
-+ CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call
-+ flush_cache_range or flush_icache_range. On some architectures,
-+ these functions may not be safe to call on SMP since we keep other
-+ CPUs in a holding pattern.
-+ </para>
-+ </listitem>
-+ </itemizedlist>
-+ </para>
-+ <para>
-+ There are also the following functions for the common backend,
-+ found in kernel/kgdb.c that must be supplied by the
-+ architecture-specific backend. No weak version of these is provided.
-+ </para>
-+!Iinclude/linux/kgdb.h
-+ </chapter>
-+ <chapter id="CommonBackEndOpt">
-+ <title>The common backend (optional)</title>
-+ <para>
-+ These functions are part of the common backend, found in kernel/kgdb.c
-+ and are optionally implemented. Some functions (with _hw_ in the name)
-+ end up being required on arches which use hardware breakpoints.
-+ </para>
-+!Ikernel/kgdb.c
-+ </chapter>
-+ <chapter id="DriverSpecificFunctions">
-+ <title>Driver-Specific Functions</title>
-+ <para>
-+ Some of the I/O drivers have additional functions that can be
-+ called, that are specific to the driver. Calls from other places
-+ to these functions must be wrapped in #ifdefs for the driver in
-+ question.
-+ </para>
-+!Idrivers/serial/8250_kgdb.c
-+ </chapter>
-+</book>
-diff -Nauprw linux-2.6.20/Documentation/DocBook/Makefile ../new/linux-2.6.20/Documentation/DocBook/Makefile
---- linux-2.6.20/Documentation/DocBook/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/DocBook/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -11,7 +11,8 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
- procfs-guide.xml writing_usb_driver.xml \
- kernel-api.xml filesystems.xml lsm.xml usb.xml \
- gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
-- genericirq.xml
-+ genericirq.xml \
-+ kgdb.xml
-
- ###
- # The build process is as follows (targets):
-diff -Nauprw linux-2.6.20/drivers/char/keyboard.c ../new/linux-2.6.20/drivers/char/keyboard.c
---- linux-2.6.20/drivers/char/keyboard.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/char/keyboard.c 2007-11-21 11:51:41.000000000 +0530
-@@ -1183,6 +1183,7 @@ static void kbd_keycode(unsigned int key
- sysrq_down = 0;
- if (sysrq_down && down && !rep) {
- handle_sysrq(kbd_sysrq_xlate[keycode], tty);
-+ sysrq_down = 0; /* In case we miss the 'up' event. */
- return;
- }
- #endif
-diff -Nauprw linux-2.6.20/drivers/cpufreq/Kconfig ../new/linux-2.6.20/drivers/cpufreq/Kconfig
---- linux-2.6.20/drivers/cpufreq/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/cpufreq/Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -140,4 +140,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
-
- If in doubt, say N.
-
-+config CPU_FREQ_NOMADIK
-+ tristate "cpu freq scaling support for nomadik"
-+ depends on CPU_FREQ
++/**
++ * nomadik_i2c_write_register
++ *
++ * nomadik_i2c_write_register - Write data to I2C client
++ * @client_id - Identifier for the client
++ * @data - Pointer to data to be written.
++ * @index - Register index of the client
++ * @count - Amount of data in bytes to be written
++ *
++ * Handle all register index type writes. Using the client structs for
++ * the client_id, we can call the correct register write function and
++ * ensure a two byte index has the correct byte order.
++ * Retrive the client specific information from the client id and feed it to
++ * the controller specific configuration. Then call the respective board
++ * specific routine.
++ **/
+
- endif # CPU_FREQ
-diff -Nauprw linux-2.6.20/drivers/hwmon/Kconfig ../new/linux-2.6.20/drivers/hwmon/Kconfig
---- linux-2.6.20/drivers/hwmon/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/hwmon/Kconfig 2008-09-16 23:41:15.000000000 +0530
-@@ -230,6 +230,19 @@ config SENSORS_IT87
- This driver can also be built as a module. If so, the module
- will be called it87.
-
-+config SENSORS_LIS3LV02DL
-+ tristate "LIS3LV02DL MEMS three-axis accelerometer I2C driver"
-+ depends on HWMON && I2C && EXPERIMENTAL
-+ default n
-+ help
-+ This driver provides support for the ST microelectronics LIS3LV02DL
-+ MEMS inertial sensor which provides a three-axis, I2C controlled
-+ ± 2g/± 6g digital output linear accelerometer. The accelerometer
-+ data is readable via sysfs.
++int nomadik_i2c_write_register(__u32 client_id,
++ __u8 * data, int index, int count)
++{
++ int bus_id;
++ int retval;
++ __u16 addr;
++ struct nomadik_i2c_client *client;
++ struct nomadik_i2c_private *priv;
+
-+ This driver can also be built as a module. If so, the module
-+ will be called lis3vl02dl.
++ if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
++ return retval;
+
- config SENSORS_LM63
- tristate "National Semiconductor LM63"
- depends on HWMON && I2C
-diff -Nauprw linux-2.6.20/drivers/hwmon/lis3lv02dl.c ../new/linux-2.6.20/drivers/hwmon/lis3lv02dl.c
---- linux-2.6.20/drivers/hwmon/lis3lv02dl.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/hwmon/lis3lv02dl.c 2008-09-16 23:41:59.000000000 +0530
-@@ -0,0 +1,489 @@
-+/*
-+ stmems.c
++ client = &priv_client[client_id];
++ bus_id = client->bus_id;
++ priv = &i2c_driver[bus_id];
++ addr = client->addr;
+
-+ Copyright (c) 2008 Nicholas Angelo Crespi <roundtrip@gmail.com>
++ if (down_interruptible(&nomadik_i2c[bus_id].lock))
++ return -ERESTARTSYS;
+
-+ LIS3LV02DL MEMS inertial sensor is a 3-axis - ± 2g/± 6g digital output
-+ low voltage linear accelerometer.
-+ http://www.st.com/stonline/products/literature/ds/12094/lis3lv02dl.htm
++// reset_i2c(priv);
+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
++ /* Save parameters. */
++ priv->config.slave_address = addr;
++ priv->config.status = I2C_STATUS_SLAVE_MODE;
++ priv->config.register_index = index;
++#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
++ priv->config.index_format =
++ ((client->index_width ==
++ REG8) ? I2C_BYTE_INDEX : (client->
++ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++ : I2C_HALF_WORD_BIG_ENDIAN));
++#else
++ priv->config.index_format =
++ ((client->index_width == 0)?I2C_NO_INDEX:
++ (client->index_width == REG8) ? I2C_BYTE_INDEX : (client->
++ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++ : I2C_HALF_WORD_BIG_ENDIAN));
++#endif
++ priv->config.databuffer = data;
++ priv->config.count_data = count;
++ priv->config.active_event.type = I2C_NO_EVENT;
++ priv->config.multi_operation = NOMADIK_TRUE;
++ /* Do the write */
++ priv->config.operation = I2C_WRITE;
+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
++ if (i2c_initialize(priv)) {
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ if (verify_parameters(priv)) {
++ error("Error in parameters\n");
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
+
-+ * Compile this driver with:
++ retval = write_i2c(priv);
+
-+ echo "obj-m := tiny_i2c_chip.o" > Makefile
-+ make -C <path/to/kernel/src> SUBDIRS=$PWD modules
-+ */
++ if (retval) {
++ error("Error in write_register: %d\n", retval);
++ } else if (retval == 0) {
+
-+#define DEBUG 1
-+#define VERSION "0.2"
++ if (priv->config.data_transfer_mode !=
++ I2C_TRANSFER_MODE_POLLING) {
++ retval = nomadik_i2c_wait_msg(priv, count);
++ if (retval) {
++ error
++ ("Message timeout with no handled event\n");
++ error("error waiting for i2c read: %d\n",
++ retval);
++ up(&nomadik_i2c[bus_id].lock);
++ return retval;
++ }
++ }
++ else mdelay(1);
++ priv->config.active_event.type = I2C_NO_EVENT;
++ up(&nomadik_i2c[bus_id].lock);
++ return retval;
++ }
+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/jiffies.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/err.h>
-+#include <linux/mutex.h>
-+#include <asm/arch/i2c.h>
++ up(&nomadik_i2c[bus_id].lock);
+
-+#define stmems_perror(format, arg...)
-+//printk( KERN_ERR "STMEMS: %s " format, __func__, ## arg)
-+#define stmems_pinfo(format, arg...)
-+//printk( KERN_INFO "STMEMS: %s " format, __func__, ## arg)
++ /* Neither register mode for this client, return an error */
++ return -EINVAL;
++}
+
-+/* Addresses to scan */
++/**
++ * nomadik_i2c_read_register - Read data from I2C client
++ * @client_id - Identifier for the client
++ * @data - Pointer where the read data will be written.
++ * @index - Register index of the client
++ * @count - Amount of data in bytes to be read
++ *
++ * Handle all register index type writes. Using the client structs for
++ * the client_id, we can call the correct register write function and
++ * ensure a two byte index has the correct byte order.
++ * Retrive the client specific information from the client id and feed it to
++ * the controller specific configuration. Then call the respective board
++ * specific routine.
++ **/
+
-+//static unsigned short normal_i2c[] = { 0x3A, I2C_CLIENT_END };
-+static unsigned short normal_i2c[] = { 0x1D, I2C_CLIENT_END };
++int nomadik_i2c_read_register(__u32 client_id,
++ __u8 * data, int index, int count)
++{
++ int bus_id;
++ int retval;
++ __u16 addr;
++ struct nomadik_i2c_client *client;
++ struct nomadik_i2c_private *priv;
+
-+//static unsigned short normal_i2c_range[] = { 0x00, 0xff, I2C_CLIENT_END };
++ if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
++ return retval;
+
-+/* Insmod parameters */
-+I2C_CLIENT_INSMOD_1(stmems);
++ client = &priv_client[client_id];
++ bus_id = client->bus_id;
++ priv = &i2c_driver[bus_id];
++ addr = client->addr;
+
-+/* Each client has this additional data */
-+struct stmems_data {
-+ struct i2c_client client;
-+ struct class_device *class_dev;
-+ struct mutex update_lock;
-+ char valid; /* !=0 if following fields are valid */
-+ unsigned long last_updated; /* In jiffies */
-+ int acc_x; /* Register values */
-+ int acc_y;
-+ int acc_z;
-+ u8 divisor;
-+ u8 fullscale;
-+ u8 BDU;
-+};
++ if (down_interruptible(&nomadik_i2c[bus_id].lock))
++ return -ERESTARTSYS;
+
-+/* stmems registers mnemonics */
-+/* mnemonic hex r/w default */
-+#define MEMS_WHO_AM_I 0x0F /*r 00111010 */
-+#define MEMS_OFFSET_X 0x16 /*rw calib */
-+#define MEMS_OFFSET_Y 0x17 /*rw calib */
-+#define MEMS_OFFSET_Z 0x18 /*rw calib */
-+#define MEMS_GAIN_X 0x19 /*rw calib */
-+#define MEMS_GAIN_Y 0x1A /*rw calib */
-+#define MEMS_GAIN_Z 0x1B /*rw calib */
-+#define MEMS_CTRL_REG1 0x20 /*rw 00000111 */
-+#define MEMS_CTRL_REG2 0x21 /*rw 00000000 */
-+#define MEMS_CTRL_REG3 0x22 /*rw 00001000 */
-+#define MEMS_HP_FILTER RESET 0x23 /*r dummy */
-+#define MEMS_STATUS_REG 0x27 /*rw 00000000 */
-+#define MEMS_OUTX_L 0x28 /*r */
-+#define MEMS_OUTX_H 0x29 /*r */
-+#define MEMS_OUTY_L 0x2A /*r */
-+#define MEMS_OUTY_H 0x2B /*r */
-+#define MEMS_OUTZ_L 0x2C /*r */
-+#define MEMS_OUTZ_H 0x2D /*r */
-+#define MEMS_FF_WU_CFG 0x30 /*rw 00000000 */
-+#define MEMS_FF_WU_SRC 0x31 /*rw 00000000 */
-+#define MEMS_FF_WU_ACK 0x32 /*r */
-+#define MEMS_FF_WU_THS_L 0x34 /*rw 00000000 */
-+#define MEMS_FF_WU_THS_H 0x35 /*rw 00000000 */
-+#define MEMS_FF_WU_DURATION 0x36 /*rw 00000000 */
-+#define MEMS_DD_CFG 0x38 /*rw 00000000 */
-+#define MEMS_DD_SRC 0x39 /*rw 00000000 */
-+#define MEMS_DD_ACK 0x3A /*r */
-+#define MEMS_DD_THSI_L 0x3C /*rw 00000000 */
-+#define MEMS_DD_THSI_H 0x3D /*rw 00000000 */
-+#define MEMS_DD_THSE_L 0x3E /*rw 00000000 */
-+#define MEMS_DD_THSE_H 0x3F /*rw 00000000 */
++// reset_i2c(priv);
+
++ /* Save parameters. */
++ priv->config.slave_address = addr;
++ priv->config.status = I2C_STATUS_SLAVE_MODE;
++ priv->config.register_index = index;
++#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
++ priv->config.index_format =
++ ((client->index_width ==
++ REG8) ? I2C_BYTE_INDEX : (client->
++ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++ : I2C_HALF_WORD_BIG_ENDIAN));
+
-+static int stmems_attach_adapter(struct i2c_adapter *adapter);
-+static int stmems_detect(struct i2c_adapter *adapter, int address, int kind);
-+static int stmems_detach_client(struct i2c_client *client);
-+static void stmems_init_sensor(struct i2c_client *client);
-+static inline u8 stmems_read_value(struct i2c_client *client, u8 reg);
-+static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value);
-+static inline int stmems_join(u8 LSB, u8 MSB);
-+static struct stmems_data *stmems_update_device(struct device *dev);
++#else
+
-+/* This is the driver that will be inserted */
-+static struct i2c_driver stmems_driver = {
-+ .driver = {
-+ .name = "stmems",
-+ },
-+ .attach_adapter = stmems_attach_adapter,
-+ .detach_client = stmems_detach_client,
-+};
++ priv->config.index_format =
++ ((client->index_width == 0)?I2C_NO_INDEX:
++ (client->index_width ==
++ REG8) ? I2C_BYTE_INDEX : (client->
++ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++ : I2C_HALF_WORD_BIG_ENDIAN));
+
-+/* read routines for accelerations */
-+#define show(value) \
-+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-+{ \
-+ struct stmems_data *data = stmems_update_device(dev); \
-+ return sprintf(buf, "%d\n", data->value); \
++#endif
++ priv->config.databuffer = data;
++ priv->config.count_data = count;
++ priv->config.active_event.type = I2C_NO_EVENT;
++ priv->config.multi_operation = NOMADIK_TRUE;
++ /* Do the read operation */
++ priv->config.operation = I2C_READ;
++
++ if (i2c_initialize(priv)) {
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
++
++ if (verify_parameters(priv)) {
++ error("Error in parameters\n");
++ up(&nomadik_i2c[bus_id].lock);
++ return -EINVAL;
++ }
++
++ retval = read_i2c(priv);
++
++ if (retval) {
++ error("Error in read register: %d\n", retval);
++ } else if (retval == 0) {
++
++ if (priv->config.data_transfer_mode !=
++ I2C_TRANSFER_MODE_POLLING) {
++ retval = nomadik_i2c_wait_msg(priv, count);
++ if (retval) {
++ error
++ ("Message timeout with no handled event\n");
++ error("error waiting for i2c read: %d\n",
++ retval);
++ up(&nomadik_i2c[bus_id].lock);
++ return retval;
++ }
++ }
++ else mdelay(1);
++ priv->config.active_event.type = I2C_NO_EVENT;
++ up(&nomadik_i2c[bus_id].lock);
++ return 0;
++ }
++
++ up(&nomadik_i2c[bus_id].lock);
++
++ /* Neither register mode for this client, return an error */
++ return -EINVAL;
+}
-+show(acc_x);
-+show(acc_y);
-+show(acc_z);
+
-+/* read routines for divisor, BDU and fullscale */
-+static ssize_t show_divisor(struct device *dev, struct device_attribute *attr, char *buf)
++static unsigned int nomadik_i2c_func(struct i2c_adapter *adap)
+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ if (!(data->valid))
-+ data = stmems_update_device(dev);
-+ return sprintf(buf, "%d\n", data->divisor);
++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK;
++ //return I2C_FUNC_I2C;
+}
+
-+static ssize_t show_fullscale(struct device *dev, struct device_attribute *attr, char *buf)
++static int nomadik_i2c_remove(struct platform_device *pdev)
+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ if (!(data->valid))
-+ data=stmems_update_device(dev);
-+ return sprintf(buf, "%d\n", data->fullscale);
-+}
-+static ssize_t show_BDU(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ if (!(data->valid))
-+ data=stmems_update_device(dev);
-+ return sprintf(buf, "%d\n", data->BDU);
-+}
-+
-+/* this macro is useless! */
-+#define set(value, reg) \
-+static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
-+{ \
-+ struct i2c_client *client = to_i2c_client(dev); \
-+ struct stmems_data *data = i2c_get_clientdata(client); \
-+ int temp = simple_strtoul(buf, NULL, 10); \
-+ \
-+ mutex_lock(&data->update_lock); \
-+ data->value = temp; \
-+ mutex_unlock(&data->update_lock); \
-+ return count; \
-+}
-+
-+/* Write routines for divisor, BDU and fullscale */
-+static ssize_t set_divisor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ u8 ctrl_reg;
-+ int temp = simple_strtoul(buf, NULL, 10);
-+ /* the divisor input can only be 512,128,32 or 8 */
-+ if ((temp!= 8) && (temp!= 32) && (temp!= 128) && (temp!= 512)) return 0;
-+ mutex_lock(&data->update_lock);
-+ data->divisor = temp;
-+ ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG1);
-+ if (temp == 8) {ctrl_reg |= 0x30;}
-+ else if (temp == 32) {ctrl_reg |= 0x20; ctrl_reg &= 0xEF;}
-+ else if (temp == 128) {ctrl_reg |= 0x10; ctrl_reg &= 0xDF;}
-+ else {ctrl_reg &= 0xCF; }
-+ stmems_write_value(client,MEMS_CTRL_REG1,ctrl_reg);
-+ mutex_unlock(&data->update_lock);
-+ return count;
-+}
-+
-+static ssize_t set_fullscale(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ u8 ctrl_reg;
-+ int temp = simple_strtoul(buf, NULL, 10);
-+ if ((temp!= 1) && (temp!= 0)) return 0;
-+ mutex_lock(&data->update_lock);
-+ data->fullscale = temp;
-+ ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
-+ if (temp) {ctrl_reg |= 0x80;}
-+ else {ctrl_reg &= 0x7F; }
-+ stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
-+ mutex_unlock(&data->update_lock);
-+ return count;
-+}
+
-+static ssize_t set_BDU(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ u8 ctrl_reg;
-+ int temp = simple_strtoul(buf, NULL, 10);
-+ if ((temp!= 1) && (temp!= 0)) return 0;
-+ mutex_lock(&data->update_lock);
-+ data->BDU = temp;
-+ ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
-+ if (temp) {ctrl_reg |= 0x40;}
-+ else {ctrl_reg &= 0xBF; }
-+ stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
-+ mutex_unlock(&data->update_lock);
-+ return count;
-+}
++ int retval;
++ i2c_del_adapter(&nomadik_i2c[pdev->id]);
+
-+static DEVICE_ATTR(acc_x, S_IRUGO,
-+ show_acc_x, NULL);
-+static DEVICE_ATTR(acc_y, S_IRUGO,
-+ show_acc_y, NULL);
-+static DEVICE_ATTR(acc_z, S_IRUGO,
-+ show_acc_z, NULL);
++ free_irq(i2c_driver[pdev->id].irq, &i2c_driver[pdev->id]);
+
-+static DEVICE_ATTR(fullscale, S_IWUSR | S_IRUGO,
-+ show_fullscale, set_fullscale);
-+static DEVICE_ATTR(divisor, S_IWUSR | S_IRUGO,
-+ show_divisor, set_divisor);
-+static DEVICE_ATTR(BDU, S_IWUSR | S_IRUGO,
-+ show_BDU, set_BDU);
++ disable_i2c(&i2c_driver[pdev->id]);
+
-+static int stmems_attach_adapter(struct i2c_adapter *adapter)
-+{
-+ int err;
-+
-+ stmems_pinfo("entered\n");
-+ stmems_pinfo("adapter class: %d\n", adapter->class);
-+
-+ if (!(adapter->class & I2C_CLASS_HWMON))
-+ {
-+ stmems_perror("adapter class is not HWMON skip\n");
-+ return 0;
++ retval =
++ nomadik_gpio_altfuncdisable(GPIO_ALT_I2C_0 + pdev->id, (char *)pdev->name);
++ if (retval) {
++ error("GPIO Disable Alt Function(%d) failed with %d\n",
++ pdev->id, retval);
++ return retval;
+ }
+
-+ err = i2c_probe(adapter, &addr_data, stmems_detect);
-+
-+ return err;
++ return 0;
+}
+
-+
-+/* This function is called by i2c_probe */
-+static int stmems_detect(struct i2c_adapter *adapter, int address, int kind)
++static int nomadik_i2c_probe(struct platform_device *pdev)
+{
-+ struct i2c_client *new_client = NULL;
-+ struct stmems_data *data = NULL;
-+ int err = 0;
-+ u8 temp_reg;
-+ int ret;
-+
-+
-+ stmems_pinfo("entered\n");
-+
-+ stmems_pinfo("kind: %d\n", kind);
-+ stmems_pinfo("address: %d\n", address);
-+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-+ {
-+ stmems_perror("no SMBUS BYTE functionality detected\n");
-+ goto error;
-+ }
++ int irq;
++ int retval = -EINVAL;
++ struct resource *res = NULL;
+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE))
-+ {
-+ stmems_perror("no SMBUS READ BYTE DATA functionality detected\n");
-+ goto error;
++ /*Fetch the Resources, using platform data */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "probe - MEM resources not defined\n");
++ return -ENODEV;
+ }
+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA))
-+ {
-+ stmems_perror("no SMBUS READ BYTE functionality detected\n");
-+ goto error;
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "probe - IRQ resource not defined\n");
++ return -ENODEV;
+ }
+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
-+ {
-+ stmems_perror("no SMBUS WRITE BYTE DATA functionality detected\n");
-+ goto error;
-+ }
++ i2c_driver[pdev->id].regs = (void *)IO_ADDRESS(res->start);
++ i2c_driver[pdev->id].id = pdev->id;
++ i2c_driver[pdev->id].irq = irq;
++ i2c_driver[pdev->id].adap = &nomadik_i2c[pdev->id];
+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
-+ {
-+ stmems_perror("no SMBUS WRITE BYTE functionality detected\n");
-+ goto error;
-+ }
++ nomadik_i2c[pdev->id].data = (void *)&i2c_driver[pdev->id];
++ nomadik_i2c[pdev->id].dev.parent = &pdev->dev;
+
-+ /* OK. For now, we presume we have a valid client. We now create the
-+ client structure, even though we cannot fill it completely yet.
-+ But it allows us to access stmems_{read,write}_value. */
-+ data = kzalloc(sizeof(struct stmems_data), GFP_KERNEL);
-+ if (!data) {
-+ err = -ENOMEM;
-+ goto error;
++ retval = i2c_add_adapter(&nomadik_i2c[pdev->id]);
++ if (retval) {
++ error("Nomadik I2C[%d] Error: failed to add adapter\n",
++ pdev->id);
++ return retval;
+ }
+
-+ memset(data, 0x00, sizeof(*data));
++ /* Initialize semaphores */
++ sema_init(&nomadik_i2c[pdev->id].lock, 1);
+
-+ new_client = &data->client;
-+ i2c_set_clientdata(new_client, data);
-+ new_client->addr = address;
-+ new_client->adapter = adapter;
-+ new_client->driver = &stmems_driver;
-+ new_client->flags = 0;
-+
-+ /* Chip detection:
-+ since the chip has a register that holds its hardware address,
-+ we use that as an identification field. */
-+ if (kind < 0){
-+ temp_reg = stmems_read_value(new_client, MEMS_WHO_AM_I);
-+ //if ( (int)temp_reg != address)
-+ // goto free_error;
++ retval = request_irq(i2c_driver[pdev->id].irq,
++ nomadik_i2c_irq_handler,
++ 0,
++ nomadik_i2c[pdev->id].name, &i2c_driver[pdev->id]);
++ if (retval < 0) {
++ error("i2c[%d] can't get requested irq %d\n",
++ pdev->id, i2c_driver[pdev->id].irq);
++ return retval;
+ }
+
-+ /* Fill in the remaining client fields */
-+ strncpy(new_client->name, "stmems", I2C_NAME_SIZE);
-+ data->valid = 0;
-+ mutex_init(&data->update_lock);
-+
-+ /* Tell the I2C layer a new client has arrived */
-+ err = i2c_attach_client(new_client);
-+ if (err)
-+ goto error;
-+
-+ /* Initialize the chip */
-+ stmems_init_sensor(new_client);
-+
-+ /* Register sysfs hooks */
-+ data->class_dev = hwmon_device_register(&new_client->dev);
-+ if (IS_ERR(data->class_dev)) {
-+ err = PTR_ERR(data->class_dev);
-+ goto detach_error;
++ if (pdev->id == 0) {
++ retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
++ if (retval) {
++ error
++ ("GPIO Enable Alt Function(%d) failed with return = %d\n",
++ pdev->id, retval);
++ return (-EIO);
++ }
++ } else {/*
++ retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_1, "I2C_1");
++ if (retval) {
++ error
++ ("GPIO Enable Alt Function(%d) failed with return = %d\n",
++ pdev->id, retval);
++ return (-EIO);
++ }*/
+ }
-+
-+ ret = device_create_file(&new_client->dev, &dev_attr_acc_x);
-+ ret = device_create_file(&new_client->dev, &dev_attr_acc_y);
-+ ret = device_create_file(&new_client->dev, &dev_attr_acc_z);
-+ ret = device_create_file(&new_client->dev, &dev_attr_divisor);
-+ ret = device_create_file(&new_client->dev, &dev_attr_fullscale);
-+ ret = device_create_file(&new_client->dev, &dev_attr_BDU);
++ init_waitqueue_head(&i2c_driver[pdev->id].event_wq);
++ reset_i2c(&i2c_driver[pdev->id]);
+ return 0;
-+
-+detach_error:
-+ i2c_detach_client(new_client);
-+//free_error:
-+ kfree(data);
-+error:
-+ return err;
+}
+
-+//TODO: powerdown
-+static int stmems_detach_client(struct i2c_client *client)
++static struct platform_driver nomadik_i2c_driver = {
++ .probe = nomadik_i2c_probe,
++ .remove = nomadik_i2c_remove,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "NOMADIK-I2C",
++ },
++};
++
++static int __init i2c_nomadik_init(void)
+{
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ hwmon_device_unregister(data->class_dev);
-+ i2c_detach_client(client);
-+ kfree(data);
-+ return 0;
++ return platform_driver_register(&nomadik_i2c_driver);
+}
+
-+/* Configure the chip, mainly with default values */
-+static void stmems_init_sensor(struct i2c_client *client){
-+ u8 conf_reg;
-+ /* CTRL_REG1: enable axis, turn down powerdown mode, freq divisor 512 */
-+
-+ conf_reg = 0xC7;
-+
-+ stmems_pinfo("entered\n");
-+
-+ stmems_write_value(client, MEMS_CTRL_REG1, conf_reg);
-+ /* CTRL_REG2: fullscale 2g, batch update, big endian, disable INT,
-+ 12bit right-justified, */
-+ conf_reg = stmems_read_value(client, MEMS_CTRL_REG2);
-+ conf_reg = 0x60;
-+
-+ stmems_write_value(client, MEMS_CTRL_REG2, conf_reg);
-+ /* CTRL_REG3: disable interrupts generation, leave others values*/
-+ conf_reg = stmems_read_value(client, MEMS_CTRL_REG3);
-+ conf_reg &= 0x8F;
-+ stmems_write_value(client, MEMS_CTRL_REG3, conf_reg);
++static void __exit i2c_nomadik_exit(void)
++{
++ platform_driver_unregister(&nomadik_i2c_driver);
+ return;
+}
+
-+static struct stmems_data *stmems_update_device(struct device *dev)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct stmems_data *data = i2c_get_clientdata(client);
-+ u8 status_reg;
++EXPORT_SYMBOL(nomadik_i2c_get_info);
++EXPORT_SYMBOL(nomadik_i2c_is_busy);
++EXPORT_SYMBOL(nomadik_i2c_read_register);
++EXPORT_SYMBOL(nomadik_i2c_write_register);
++EXPORT_SYMBOL(nomadik_i2c_get_client);
+
-+ stmems_pinfo("entered\n");
++module_init(i2c_nomadik_init);
++module_exit(i2c_nomadik_exit);
+
-+ mutex_lock(&data->update_lock);
-+ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-+ status_reg = stmems_read_value(client, MEMS_STATUS_REG);
-+ //TODO: we're assuming big endianess
-+ //TODO: use 0x08 instead
-+ if (status_reg & 0x01)
-+ data->acc_x = stmems_join(stmems_read_value(client, MEMS_OUTX_H), stmems_read_value(client, MEMS_OUTX_L));
-+ if (status_reg & 0x02)
-+ data->acc_y = stmems_join(stmems_read_value(client, MEMS_OUTY_H), stmems_read_value(client, MEMS_OUTY_L));
-+ if (status_reg & 0x04)
-+ data->acc_z = stmems_join(stmems_read_value(client, MEMS_OUTZ_H), stmems_read_value(client, MEMS_OUTZ_L));
-+ data->last_updated = jiffies;
-+ data->valid = 1;
-+ mutex_unlock(&data->update_lock);
++MODULE_DESCRIPTION("Nomadik IIC driver v" DRIVER_VERSION);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h
+@@ -0,0 +1,93 @@
++/* drivers/i2c/busses/i2c-nomadik.h
++ *
++ * This is the non-public header file for the nomadik i2c driver.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * $Id$
++ */
+
-+ if (data)
-+ {
-+ stmems_pinfo("acc_x: %d\n", data->acc_x);
-+ stmems_pinfo("acc_y: %d\n", data->acc_y);
-+ stmems_pinfo("acc_z: %d\n", data->acc_z);
-+ }
-+
-+ return data;
-+}
++#ifndef I2C_NOMADIC_PRIV_HEADER
++#define I2C_NOMADIC_PRIV_HEADER
+
-+/* All registers are byte-sized */
-+static inline u8 stmems_read_value(struct i2c_client *client, u8 reg)
-+{
-+ u8 temp;
++#ifndef _NOMADIK_DEFS_H
++#include <asm/arch/defs.h>
++#endif
+
-+ stmems_pinfo("reading: 0x%02X\n", reg);
-+ temp = i2c_smbus_read_byte_data(client, reg);
-+ //nomadik_i2c_read_register(I2C_MEMS_CLIENT,&temp,reg,1);
-+ stmems_pinfo("read: 0x%02X, value: 0x%02X\n", reg, temp);
-+
-+ return temp;
-+}
++#ifndef I2C_NOMADIC_HEADER
++#include <asm/arch/i2c.h>
++#endif
+
-+static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value)
-+{
-+ stmems_pinfo("writing: 0x%02X, value: 0x%02X\n", reg, value);
++#define I2C_ALGO_NOMADIK 0x15000000
++#define I2C_HW_NOMADIK 0x01
++#define I2C_DRIVERID_NOMADIK 0xF000
+
-+ return i2c_smbus_write_byte_data(client, reg, value);
-+ //return nomadik_i2c_write_register(I2C_MEMS_CLIENT,&value,reg,1);
-+}
++#define I2C0_IOSIZE 0x00000FFF
++#define I2C1_IOSIZE 0x00000FFF
+
-+static int __init stmems_init(void)
-+{
-+ stmems_pinfo("entered\n");
++#define MSG_WAIT_USEC 500 // Wait 500 uSecs to test active event again.
++#define MAX_WIAT_TIMEOUTS 100
+
-+ return i2c_add_driver(&stmems_driver);
-+}
++/***
++ * Other structs
++ ***/
++struct nomadik_i2c_client {
++ __u32 id;
++ __u32 bus_id;
++ __u8 addr;
++ __u8 endianness; // This indicates endianness of device's register index
++ __u8 index_width; // 8 or 16 bits;
++};
+
-+static void __exit stmems_exit(void)
-+{
-+ stmems_pinfo("entered\n");
++#define BIG_END 0
++#define LITTLE_END 1
++#define REG8 8
++#define REG16 16
+
-+ i2c_del_driver(&stmems_driver);
-+}
++struct nomadik_i2c_private {
++ __u32 id; // bus id
++ struct i2c_adapter *adap;
++ int irq;
++ struct semaphore sema; // Use for blocking on aa message completion
++ int fast_mode;
++ void __iomem *regs;
++ wait_queue_head_t event_wq;
++ struct i2c_controller_config config;
++};
+
-+static inline int stmems_join(u8 LSB, u8 MSB)
++static inline int nomadik_i2c_check_client_id(__u32 id)
+{
-+ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
-+ if (MSB & 0x10)
-+ MSB |= 0xE0;
-+ return (s16)(LSB | ((MSB << 8)));
++ if ((id < 0) || (id >= I2C_NUM_CLIENTS)) {
++ return -EINVAL;
++ }
++ return 0;
+}
+
-+MODULE_AUTHOR("Nicholas Angelo Crespi <roundtrip@gmail.com>");
-+MODULE_DESCRIPTION("LIS3LV02DL MEMS three-axis accelerometer I2C driver");
-+MODULE_VERSION(VERSION);
-+MODULE_LICENSE("GPL");
++/*-----------------------------------------------------------------------------
++ Configuration functions
++-----------------------------------------------------------------------------*/
++int setup_i2c_controller(struct nomadik_i2c_private *priv);
+
-+module_init(stmems_init);
-+module_exit(stmems_exit);
-diff -Nauprw linux-2.6.20/drivers/hwmon/Makefile ../new/linux-2.6.20/drivers/hwmon/Makefile
---- linux-2.6.20/drivers/hwmon/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/hwmon/Makefile 2008-09-16 23:41:15.000000000 +0530
-@@ -30,6 +30,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm
- obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
- obj-$(CONFIG_SENSORS_IT87) += it87.o
- obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
-+obj-$(CONFIG_SENSORS_LIS3LV02DL)+= lis3lv02dl.o
- obj-$(CONFIG_SENSORS_LM63) += lm63.o
- obj-$(CONFIG_SENSORS_LM70) += lm70.o
- obj-$(CONFIG_SENSORS_LM75) += lm75.o
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c
---- linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c 2008-10-20 13:37:45.000000000 +0530
-@@ -0,0 +1,1250 @@
++int write_i2c(struct nomadik_i2c_private *priv);
+
-+/* drivers/i2c/busses/i2c-nomadik.c
++int read_i2c(struct nomadik_i2c_private *priv);
++
++int process_interrupt(struct nomadik_i2c_private *priv);
++int verify_parameters(struct nomadik_i2c_private *priv);
++void reset_i2c(struct nomadik_i2c_private *priv);
++void disable_i2c(struct nomadik_i2c_private *priv);
++void stn_cut_mdelay(int dlytime);
++
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c
+@@ -0,0 +1,1723 @@
++
++/* drivers/i2c/busses/i2c-nmdk8810.c
+ *
-+ * Support for i2c bus on STn8800/8810/8815 (Nomadik) chips.
++ * Support for i2c bus on STn8810 (Nomadik) chips.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
++ * Author: Melwyn LOBO <melwyn.lobo@st.com>
++ *-----------------------------------------------------------------------------
+ */
+
++
+#include <linux/module.h>
+#include <linux/kernel.h>
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <linux/i2c.h>
-+#include <linux/platform_device.h>
-+#include <linux/i2c-id.h>
-+#include <asm/hardware.h>
++
+#include "i2c-nomadik.h"
-+#include <asm/arch/gpio.h>
-+#define DRIVER_VERSION "2.0.0"
-+#define width 0
-+#define BUSID 1
-+#define error(format, arg...) printk( KERN_ERR "I2C: " format , ## arg)
-+#define info(format, arg...)
-+/*printk( KERN_INFO "I2C: %s " format, __func__, ## arg)*/
++#include <linux/delay.h>
+
-+static unsigned int nomadik_i2c_func(struct i2c_adapter *adap);
-+static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
-+ struct i2c_msg msgs[], int num);
-+static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
-+ struct i2c_msg msgs[], int num);
++#define I2C_ENDAD_COUNTER 50000
++#define I2C_INT_ENDED_COUNTER 50000
++#define I2C_BTF_COUNTER 50000
++#define I2C_BTF_COUNTER_POLLING 50000
++#define I2C_FIFO_FLUSH_COUNTER 500
++#define I2C_LOWER_SLAVE 127
++#define I2C_UPPER_SLAVE 1024
+
-+/* Other variables indexed by bus */
-+static struct nomadik_i2c_private i2c_driver[2];
++/*#######################################################################
++ Macros to access I2C Registers with their offsets
++#########################################################################
++*/
+
-+static struct i2c_algorithm nomadik_i2c_algo = {
-+ master_xfer:nomadik_i2c_xfer,
-+ smbus_xfer:NULL,
-+ algo_control:NULL,
-+ functionality:nomadik_i2c_func
-+};
++#define I2C_REG_OFFSET_CR 0x00
++#define I2C_REG_OFFSET_SR1 0x04
++#define I2C_REG_OFFSET_SR2 0x08
++#define I2C_REG_OFFSET_CCR 0x0C
++#define I2C_REG_OFFSET_OAR1 0x10
++#define I2C_REG_OFFSET_OAR2 0x14
++#define I2C_REG_OFFSET_DR 0x18
++#define I2C_REG_OFFSET_ECCR 0x1C
+
-+static struct i2c_adapter nomadik_i2c[2] = { {
-+ name: "i2c0",
-+ id: I2C_ALGO_NOMADIK |
-+ I2C_HW_NOMADIK,
-+ algo: &nomadik_i2c_algo,
-+ data: &i2c_driver[0],
-+ class: I2C_CLASS_HWMON
++/*#######################################################################
++ Macros to access I2C Interrupt Registers event
++#########################################################################
++*/
+
-+ },
-+{
-+ name:"i2c1",
-+ id:I2C_ALGO_NOMADIK | I2C_HW_NOMADIK,
-+ algo:&nomadik_i2c_algo,
-+ data:&i2c_driver[1],
-+ }
-+};
++#define I2C0_IRQ_SRC_ALL 0
++#define I2C1_IRQ_SRC_ALL 1
+
-+#if !defined (CONFIG_NOMADIK_NHK15)
-+static struct i2c_client nomadik_i2c_clients[] = {
-+ {
-+ name:"motherboard",
-+ id:I2C_MB_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_MB,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"ui db",
-+ id:I2C_UI_DB_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_UI_DB,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"io expansion db1",
-+ id:I2C_IO_EXP_DB1_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_IO_DB1,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"io expansion db2",
-+ id:I2C_IO_EXP_DB2_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_IO_DB2,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"Matisse camera",
-+ id:I2C_CIF_CAM_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_CIF_CAM,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"mem exp",
-+ id:I2C_MEM_EXP_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_MEM_EXP,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"audio codec",
-+ id:I2C_AUDIO_CODEC_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_AC,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"FM tuner",
-+ id:I2C_FM_TUNER_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_FM_TUNER,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"Gas Gauge",
-+ id:I2C_GAS_GAUGE_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_GAS_GAUGE,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"Matiise for litea cam",
-+ id:I2C_LITEA_CAM_MOD_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_CAM_MOD,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"i2c0 loopback",
-+ id:I2C0_LOOP_CLIENT,
-+ flags:0,
-+ addr:I2C0_LP_OWNADDR,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {
-+ name:"i2c1 loopback",
-+ id:I2C1_LOOP_CLIENT,
-+ flags:0,
-+ addr:I2C1_LP_OWNADDR,
-+ adapter:&nomadik_i2c[1]
-+ },
-+ {
-+ name:"Pepperpot camera",
-+ id:I2C_PP_CAM_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_PP_CAM,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {
-+ name:"Touareg",
-+ id:I2C_TOUAREG_CLIENT,
-+ adapter:&nomadik_i2c[I2C_TOUAREG_ADAPTER],
-+ flags:0,
-+ addr:I2C_ADDR_TOUAREG,
-+ }
++#define I2C_IT_BTF STD_MASK_BIT0
++#define I2C_IT_ADSL STD_MASK_BIT1
++#define I2C_IT_SB STD_MASK_BIT2
++#define I2C_IT_AF STD_MASK_BIT3
++#define I2C_IT_STOPF STD_MASK_BIT4
++#define I2C_IT_ARLO STD_MASK_BIT5
++#define I2C_IT_BERR STD_MASK_BIT6
++#define I2C_IT_ADD10 STD_MASK_BIT7
++#define I2C_IT_SCLFAL STD_MASK_BIT8
++#define I2C_IT_ENDAD STD_MASK_BIT9
+
-+};
-+#else
-+static struct i2c_client nomadik_i2c_clients[] = {
-+ {//0x42
-+ name:"Denc",
-+ id:I2C_DENC_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_DENC,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//0x34
-+ name:"audio codec",
-+ id:I2C_AUDIO_CODEC_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_AC,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//0x20
-+ name:"FM tuner",
-+ id:I2C_FM_TUNER_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_FM_TUNER,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//FIXME
-+ name:"Matiise for litea cam",
-+ id:I2C_LITEA_CAM_MOD_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_CAM_MOD,
-+ adapter:&nomadik_i2c[BUSID]
-+ },
-+ {//0x3A
-+ name:"mems",
-+ id:I2C_MEMS_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_MEMS,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//0x44, 0x46
-+ name:"SIM card",
-+ id:I2C_SIM_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_SIM,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//0x90
-+ name:"touch screen",
-+ id:I2C_TOUCH_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_TOUCH,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//0x86
-+ name: "PEXP0",
-+ id:I2C_STMPE0_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_STMPE0,
-+ adapter:&nomadik_i2c[0],
-+ },
-+ {//0x88
-+ name: "PEXP1",
-+ id:I2C_STMPE1_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_STMPE1,
-+ adapter:&nomadik_i2c[0],
-+ },
-+ {//0xE0
-+ name:"Gas Gauge",
-+ id:I2C_GAS_GAUGE_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_GAS_GAUGE,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {//0x5A FIXME - MMC
-+ name:"Power manager",
-+ id:I2C_TOUAREG_CLIENT,
-+ flags:0,
-+ addr:I2C_ADDR_POWER,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {
-+ name:"i2c0 loopback",
-+ id:I2C0_LOOP_CLIENT,
-+ flags:0,
-+ addr:I2C0_LP_OWNADDR,
-+ adapter:&nomadik_i2c[0]
-+ },
-+ {
-+ name:"i2c1 loopback",
-+ id:I2C1_LOOP_CLIENT,
-+ flags:0,
-+ addr:I2C1_LP_OWNADDR,
-+ adapter:&nomadik_i2c[1]
-+ },
++/*#######################################################################
++ I2C Control Register
++#########################################################################
++*/
+
-+};
-+#endif
++#define I2C_ITE STD_MASK_BIT0
++#define I2C_STOP STD_MASK_BIT1
++#define I2C_ACK STD_MASK_BIT2
++#define I2C_START STD_MASK_BIT3
++#define I2C_ENGC STD_MASK_BIT4
++#define I2C_PE STD_MASK_BIT5
++#define I2C_TRANS STD_MASK_BIT6
++#define I2C_DDC1EN STD_MASK_BIT7
++#define I2C_SHIFT_ITE 0
++#define I2C_SHIFT_STOP 1
++#define I2C_SHIFT_ACK 2
++#define I2C_SHIFT_START 3
++#define I2C_SHIFT_ENGC 4
++#define I2C_SHIFT_PE 5
++#define I2C_SHIFT_TRANS 6
++#define I2C_SHIFT_DDC1EN 7
+
-+#if !defined(CONFIG_NOMADIK_NHK15)
++/*#######################################################################
++ I2C Status Register1
++#########################################################################
++*/
+
-+/* This is an array of bus ids indexed by client id. They MUST be in the
-+ sam order as the client structs above
-+ */
-+static __u32 nomadik_client_bus_id[] =
-+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, I2C_CLIENT_BUSID13 };
++#define I2C_SB STD_MASK_BIT0
++#define I2C_MASTER STD_MASK_BIT1
++#define I2C_ADSL STD_MASK_BIT2
++#define I2C_BTF STD_MASK_BIT3
++#define I2C_BUSY STD_MASK_BIT4
++#define I2C_TRA STD_MASK_BIT5
++#define I2C_ADD10 STD_MASK_BIT6
++#define I2C_EVF STD_MASK_BIT7
++#define I2C_SHIFT_SB 0
++#define I2C_SHIFT_MASTER 1
++#define I2C_SHIFT_ADSL 2
++#define I2C_SHIFT_BTF 3
++#define I2C_SHIFT_BUSY 4
++#define I2C_SHIFT_TRA 5
++#define I2C_SHIFT_ADD10 6
++#define I2C_SHIFT_EVF 7
+
-+static struct nomadik_i2c_client priv_client[] = {
-+ {
-+ id:I2C_MB_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_MB,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_UI_DB_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_UI_DB,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_IO_EXP_DB1_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_IO_DB1,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_IO_EXP_DB2_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_IO_DB2,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_CIF_CAM_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_CIF_CAM,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C_MEM_EXP_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_MEM_EXP,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_AUDIO_CODEC_CLIENT,
-+ bus_id:1,
-+ addr:I2C_ADDR_AC,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C_FM_TUNER_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_FM_TUNER,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_GAS_GAUGE_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_GAS_GAUGE,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_LITEA_CAM_MOD_CLIENT,
-+ bus_id:BUSID,
-+ addr:I2C_ADDR_CAM_MOD,
-+ endianness:LITTLE_END,
-+ index_width:REG16},
-+ {
-+ id:I2C0_LOOP_CLIENT,
-+ bus_id:0,
-+ addr:I2C0_LP_OWNADDR,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C1_LOOP_CLIENT,
-+ bus_id:1,
-+ addr:I2C1_LP_OWNADDR,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_PP_CAM_CLIENT,
-+ /* added for Pepperpot camera */
-+ bus_id:1,
-+ addr:I2C_ADDR_PP_CAM,
-+ endianness:BIG_END,
-+ index_width:REG16},
-+ {
-+ id:I2C_TOUAREG_CLIENT,
-+ /* added for Touareg chip for power mgmt */
-+ bus_id:I2C_TOUREG_CLIENT_BUSID,
-+ addr:I2C_ADDR_TOUAREG,
-+ endianness:LITTLE_END,
-+ index_width:REG8
-+#ifdef CONFIG_NOMADIK_NDK15
-+ },
-+ {
-+ id:I2C_CPLD_CLIENT,
-+ /* added for CPLD */
-+ bus_id:I2C_CPLD_CLIENT_BUSID,
-+ addr:I2C_ADDR_CPLD,
-+ endianness:LITTLE_END,
-+ /* check */
-+ index_width:REG8
-+#endif
-+ },
-+ {
-+ id:I2C_DENC_CLIENT,
-+ bus_id:1,
-+ addr:I2C_ADDR_DENC,
-+ endianness:LITTLE_END,
-+ index_width:REG8}
++/*#######################################################################
++ I2C Status Register2
++#########################################################################
++*/
+
-+};
++#define I2C_GCAL STD_MASK_BIT0
++#define I2C_BERR STD_MASK_BIT1
++#define I2C_ARLO STD_MASK_BIT2
++#define I2C_STOPF STD_MASK_BIT3
++#define I2C_AF STD_MASK_BIT4
++#define I2C_ENDAD STD_MASK_BIT5
++#define I2C_SCLFAL STD_MASK_BIT7
++#define I2C_SHIFT_GCAL 0
++#define I2C_SHIFT_BERR 1
++#define I2C_SHIFT_ARLO 2
++#define I2C_SHIFT_STOPF 3
++#define I2C_SHIFT_AF 4
++#define I2C_SHIFT_ENDAD 5
++#define I2C_SHIFT_SCLFAL 7
+
-+#else
-+/* This is an array of bus ids indexed by client id. They MUST be in the
-+ sam order as the client structs above
-+ */
-+static __u32 nomadik_client_bus_id[] =
-+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 1};
++/*#######################################################################
++ I2C Clock Control Register
++#########################################################################
++*/
+
-+static struct nomadik_i2c_client priv_client[] = {
-+ {
-+ id:I2C_DENC_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_DENC,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C_AUDIO_CODEC_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_AC,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C_FM_TUNER_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_FM_TUNER,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_LITEA_CAM_MOD_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_CAM_MOD,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_MEMS_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_MEMS,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C_SIM_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_SIM,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_TOUCH_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_TOUCH,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C_STMPE0_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_STMPE0,
-+ endianness:LITTLE_END,
-+ index_width:REG8
-+ },
-+ {
-+ id:I2C_STMPE1_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_STMPE1,
-+ endianness:LITTLE_END,
-+ index_width:REG8
-+ },
-+ {
-+ id:I2C_GAS_GAUGE_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_GAS_GAUGE,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C_TOUAREG_CLIENT,
-+ bus_id:0,
-+ addr:I2C_ADDR_POWER,
-+ endianness:LITTLE_END,
-+ index_width:REG8},
-+ {
-+ id:I2C0_LOOP_CLIENT,
-+ bus_id:0,
-+ addr:I2C0_LP_OWNADDR,
-+ endianness:LITTLE_END,
-+ index_width:0},
-+ {
-+ id:I2C1_LOOP_CLIENT,
-+ bus_id:1,
-+ addr:I2C1_LP_OWNADDR,
-+ endianness:LITTLE_END,
-+ index_width:0},
++#define I2C_CLOCK_MASK 0x7F
++#define I2C_FM_SM_MASK 0x80
+
-+};
-+#endif /*CONFIG_NOMADIK_NHK15*/
-+static int i2c_initialize(struct nomadik_i2c_private *priv)
-+{
-+ /* Transfer configuration */
-+ priv->config.freq_scl = STD_SPEED_IN_HZ;
-+ priv->config.i2c_transmit_interrupt_threshold = 4;
-+ priv->config.i2c_receive_interrupt_threshold = 4;
++/*#######################################################################
++ Default I2C Register Values
++#########################################################################
++*/
+
-+ priv->config.bus_control_mode = I2C_BUS_MASTER_MODE;
-+ priv->config.index_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
-+ priv->config.data_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
-+
-+ /* Device configuration */
-+ priv->config.freq_input = STD_F_IN_HZ;
-+
-+ if (priv->id)
-+ priv->config.own_address = I2C1_LP_OWNADDR;
-+ else
-+ priv->config.own_address = I2C0_LP_OWNADDR;
-+
-+ if (setup_i2c_controller(priv) != 0) {
-+ error("i2c device config 0 failed init\n");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * nomadik_i2c_get_info - Get status information of I2C controller
-+ *
-+ * @bus_id - The controller id.
-+ * info - Info pointer describing the controller status.
-+ *
-+ * Return an info struct with current bus parameters.
-+ **/
-+
-+int nomadik_i2c_get_info(__u32 bus_id, i2c_info_t * info)
-+{
-+ struct nomadik_i2c_private *priv;
-+ priv = &i2c_driver[bus_id];
-+ info->baseAddress = (__u32) priv->regs;
-+ info->id = priv->id;
-+ info->mode = priv->config.mode;
-+ info->enabled = priv->config.enabled;
-+ info->fSCL = priv->config.freq_scl;
-+ info->fIn = priv->config.freq_input;
-+ info->ownAddress = priv->config.own_address;
-+
-+ return 0;
-+}
-+
-+/**
-+ * nomadik_get_client - Get client information
-+ *
-+ * @client_id - Client id for the I2C device.
-+ *
-+ * This function returns the address of the client struct identified by
-+ * client_id
-+ **/
-+
-+struct i2c_client *nomadik_i2c_get_client(__u32 client_id)
-+{
-+ if ((client_id < 0) || (client_id >= I2C_NUM_CLIENTS)) {
-+ error("error: nomadik get_client: client = %d\n", client_id);
-+ return 0;
-+ }
-+ return &nomadik_i2c_clients[client_id];
-+}
-+
-+/**
-+ * nomadik_i2c_is_busy - Check if the client is busy in an operation.
-+ *
-+ * @client_id - Identifier for the client whose status is required.
-+ *
-+ * This function checks the status of an event_type I2C_NO_EVENT. If this is
-+ * the current active event, the controller is not busy, and the function
-+ * returns false (0). If this is not the current event type, then the bus is
-+ * in the process of doing something, so we return true -EBUSY. Note that there
-+ * is no guarantee that the bus will not become busy between this call and
-+ * a transfer request, so calls to the transfer functions should
-+ * check the return - it will be -EBUSY if the bus is in use. -EINVAL
-+ * is returned for an invalid client_id.
-+ **/
-+
-+int nomadik_i2c_is_busy(__u32 client_id)
-+{
-+ int retval;
-+
-+ if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
-+ return retval;
-+
-+ if (i2c_driver[nomadik_client_bus_id[client_id]].config.active_event.
-+ type == I2C_NO_EVENT)
-+ return 0;
-+ return -EBUSY;
-+}
-+
-+static irqreturn_t nomadik_i2c_irq_handler(int irq,
-+ void *arg)
-+{
-+ __u32 id = ((struct nomadik_i2c_private *)arg)->id;
-+ disable_irq(irq);
-+ process_interrupt(&i2c_driver[id]);
-+
-+ enable_irq(i2c_driver[id].irq);
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * nomadik_i2c_wait_msg
-+ *
-+ * @nomadik_i2c_private - Private data for the controller
-+ * @len - Amount of data in bytes to be transferred
-+ *
-+ * Poll until the event we've started is finished.
-+ * Wait 1000 microseconds for each byte transferred.
-+ * Here we have not used wait_event_interruptible_timeout()
-+ * as this would cause a schedule in interrupt context in case I2C routines
-+ * called by client drivers in interrupt handlers
-+ *
-+ * This function should be called ONLY by this driver.
-+ **/
-+#define WAIT_CONDITION (priv->config.active_event.type > I2C_NO_EVENT && priv->config.active_event.type <= I2C_BUS_ERROR_EVENT)
-+
-+static int nomadik_i2c_wait_msg(struct nomadik_i2c_private *priv, int len)
-+{
-+ if(wait_event_interruptible(priv->event_wq, WAIT_CONDITION))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+/**
-+ * nomadik_i2c_xfer_byte - I2C transfer function used by nomadik_i2c_xfer to
-+ * transfer a single byte
-+ * @i2c_adapter - Adapter pointer to the controller
-+ * @msgs[] - Pointer to data to be written.
-+ * @num - Num messages
-+ *
-+ **/
-+
-+static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
-+ struct i2c_msg msgs[], int num)
-+{
-+ int m, mm;
-+ int status;
-+ unsigned int addr;
-+ struct nomadik_i2c_private *priv =
-+ (struct nomadik_i2c_private *)i2c_adap->data;
-+ __u32 bus_id = priv->id;
-+ int read = 0;
-+
-+ if (msgs[0].len <= 0)
-+ return 0;
-+
-+ addr = msgs[0].addr;
-+
-+ if (msgs[0].flags & I2C_M_TEN)
-+ {
-+ error("10 bit addressing not yet supported\n");
-+ return -EINVAL;
-+ }
-+
-+ if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+ return -ERESTARTSYS;
-+
-+ for (m = 0; m < num; m++)
-+ {
-+ info("message: %d, addr: %d\n", m, msgs[m].addr);
-+ info("message: %d, flags: %d\n", m, msgs[m].flags);
-+ info("message: %d, len: %d\n", m, msgs[m].len);
-+
-+ for(mm = 0; mm < msgs[m].len; mm++)
-+ info("message: %d, buf[%d]: 0x%02X\n", m, mm, msgs[m].buf[mm]);
-+
-+ info("message: %d, bus id: 0x%02X\n", m, bus_id);
-+ }
-+
-+#if !defined(CONFIG_NOMADIK_NHK15)
-+ reset_i2c(priv);
-+#endif
-+
-+ /* Save parameters. */
-+ priv->config.slave_address = addr;
-+ priv->config.status = I2C_STATUS_SLAVE_MODE;
-+ priv->config.index_format = I2C_BYTE_INDEX;
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ priv->config.multi_operation = NOMADIK_TRUE;
-+
-+ if (i2c_initialize(priv)) {
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ if (verify_parameters(priv))
-+ {
-+ error("Error in parameters\n");
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ if (num > 1)
-+ {
-+ if (msgs[1].flags & I2C_M_RD)
-+ {
-+ read = 1;
-+ }
-+ }
-+
-+ if (read != 0)
-+ {
-+
-+ /* Save parameters. */
-+ priv->config.databuffer = &(msgs[1].buf[0]);
-+ priv->config.count_data = msgs[1].len;
-+ priv->config.register_index = msgs[0].buf[0];
-+ /* Do the read */
-+ priv->config.operation = I2C_READ;
-+
-+ status = read_i2c(priv);
-+
-+ if (status)
-+ {
-+ error("Error in read_register: %d\n", status);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return status;
-+ }
-+ else if (status == 0)
-+ {
-+
-+ if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
-+ {
-+ status = nomadik_i2c_wait_msg(priv, msgs[0].len);
-+ if (status)
-+ {
-+ error("Message timeout with no handled event\n");
-+ error("error waiting for i2c read: %d\n", status);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return status;
-+ }
-+ }
-+ }
-+
-+ info("ret message: 0, buf[0]: 0x%02X\n", msgs[0].buf[0]);
-+ info("ret message: 1, buf[0]: 0x%02X\n", msgs[1].buf[0]);
-+
-+ mdelay(1);
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+
-+ up(&nomadik_i2c[bus_id].lock);
-+ }
-+ else
-+ {
-+ /* Save parameters. */
-+ priv->config.databuffer = &(msgs[0].buf[1]);
-+ priv->config.count_data = 1;
-+ priv->config.register_index = msgs[0].buf[0];
-+
-+ /* Do the write */
-+ priv->config.operation = I2C_WRITE;
-+ status = write_i2c(priv);
-+ if (status)
-+ {
-+ error("Error in write_register: %d\n", status);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return status;
-+ }
-+ else if (status == 0)
-+ {
-+ if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
-+ {
-+ status = nomadik_i2c_wait_msg(priv, msgs[0].len - 1);
-+ if (status)
-+ {
-+ error("Message timeout with no handled event\n");
-+ error("error waiting for i2c write: %d\n", status);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return status;
-+ }
-+ }
-+ }
-+ mdelay(1);
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ up(&nomadik_i2c[bus_id].lock);
-+ }
-+
-+ return 0;
-+
-+}
-+
-+/**
-+ * nomadik_i2c_xfer - I2C transfer function used by kernel framework
-+ * @i2c_adapter - Adapter pointer to the controller
-+ * @msgs[] - Pointer to data to be written.
-+ * @num - Amount of data in bytes to be written
-+ *
-+ * This is the function called by the generic kernel i2c API calls. Note that
-+ * this code is protected by the semaphore set in the kernel i2c_transfer()
-+ * function.
-+ * Retrive the client specific information from the client id and feed it to
-+ * the controller specific configuration. Then call the respective board
-+ * specific routine.
-+ **/
-+
-+static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
-+ struct i2c_msg msgs[], int num)
-+{
-+ int i;
-+ int status;
-+ unsigned int addr;
-+ struct nomadik_i2c_private *priv =
-+ (struct nomadik_i2c_private *)i2c_adap->data;
-+ __u32 bus_id = priv->id;
-+ /*read byte or write byte, SMBus emulated (see i2c_smbus_xfer_emulated)*/
-+ if ((num == 2 && msgs[0].len == 1 && msgs[1].len == 1 && (msgs[1].flags & I2C_M_RD)) ||
-+ (num == 1 && msgs[0].len == 2 && ((msgs[0].flags & I2C_M_RD) == 0)))
-+ {
-+ return nomadik_i2c_xfer_byte(i2c_adap, msgs, num);
-+ }
-+
-+ for (i = 0; i < num; i++) { /* deal with message i */
-+ if (msgs[i].len > 0) { /*sanity check - message length */
-+ /*prepare address */
-+ addr = msgs[i].addr;
-+ if (msgs[i].flags & I2C_M_RD)
-+ addr |= 0x1;
-+
-+ if (msgs[i].flags & I2C_M_TEN) {
-+ error("10 bit addressing not yet supported\n");
-+ return -EINVAL;
-+ }
-+
-+ if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+ return -ERESTARTSYS;
-+
-+ reset_i2c(priv);
-+
-+ /* Save parameters. */
-+ priv->config.slave_address = addr;
-+ priv->config.status = I2C_STATUS_SLAVE_MODE;
-+ priv->config.index_format = I2C_NO_INDEX;
-+ priv->config.databuffer = msgs[i].buf;
-+ priv->config.count_data = msgs[i].len;
-+ priv->config.multi_operation = NOMADIK_TRUE;
-+
-+ if (i2c_initialize(priv)) {
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ if (verify_parameters(priv)) {
-+ error("Error in parameters\n");
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 1) {
-+ /* Do the read */
-+ priv->config.operation = I2C_READ;
-+ /* read */
-+ status = read_i2c(priv);
-+ if (status) {
-+ error("Error in read_register: %d\n",
-+ status);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return status;
-+ } else if (status == 0) {
-+
-+ if (priv->config.data_transfer_mode !=
-+ I2C_TRANSFER_MODE_POLLING) {
-+ status =
-+ nomadik_i2c_wait_msg(priv,
-+ msgs
-+ [i].
-+ len);
-+ if (status) {
-+ error
-+ ("Message timeout with no handled event\n");
-+ error
-+ ("error waiting for i2c read: %d\n",
-+ status);
-+ up(&nomadik_i2c[bus_id].
-+ lock);
-+ return status;
-+ }
-+ }
-+ }
-+ /* mdelay(1); */ /* NM */
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ up(&nomadik_i2c[bus_id].lock);
-+
-+ } else {
-+ /* Do the write */
-+ priv->config.operation = I2C_WRITE;
-+ status = write_i2c(priv);
-+ if (status) {
-+ error("Error in write_register: %d\n",
-+ status);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return status;
-+ } else if (status == 0) {
-+
-+ if (priv->config.data_transfer_mode !=
-+ I2C_TRANSFER_MODE_POLLING) {
-+ status =
-+ nomadik_i2c_wait_msg(priv,
-+ msgs
-+ [i].
-+ len);
-+ if (status) {
-+ error
-+ ("Message timeout with no handled event\n");
-+ error
-+ ("error waiting for i2c write: %d\n",
-+ status);
-+ up(&nomadik_i2c[bus_id].
-+ lock);
-+ return status;
-+ }
-+ }
-+ }
-+ /* mdelay(1); */ /* NM */
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ up(&nomadik_i2c[bus_id].lock);
-+ }
-+
-+ }
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * nomadik_i2c_write_register
-+ *
-+ * nomadik_i2c_write_register - Write data to I2C client
-+ * @client_id - Identifier for the client
-+ * @data - Pointer to data to be written.
-+ * @index - Register index of the client
-+ * @count - Amount of data in bytes to be written
-+ *
-+ * Handle all register index type writes. Using the client structs for
-+ * the client_id, we can call the correct register write function and
-+ * ensure a two byte index has the correct byte order.
-+ * Retrive the client specific information from the client id and feed it to
-+ * the controller specific configuration. Then call the respective board
-+ * specific routine.
-+ **/
-+
-+int nomadik_i2c_write_register(__u32 client_id,
-+ __u8 * data, int index, int count)
-+{
-+ int bus_id;
-+ int retval;
-+ __u16 addr;
-+ struct nomadik_i2c_client *client;
-+ struct nomadik_i2c_private *priv;
-+
-+ if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
-+ return retval;
-+
-+ client = &priv_client[client_id];
-+ bus_id = client->bus_id;
-+ priv = &i2c_driver[bus_id];
-+ addr = client->addr;
-+
-+ if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+ return -ERESTARTSYS;
-+
-+// reset_i2c(priv);
-+
-+ /* Save parameters. */
-+ priv->config.slave_address = addr;
-+ priv->config.status = I2C_STATUS_SLAVE_MODE;
-+ priv->config.register_index = index;
-+#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
-+ priv->config.index_format =
-+ ((client->index_width ==
-+ REG8) ? I2C_BYTE_INDEX : (client->
-+ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+ : I2C_HALF_WORD_BIG_ENDIAN));
-+#else
-+ priv->config.index_format =
-+ ((client->index_width == 0)?I2C_NO_INDEX:
-+ (client->index_width == REG8) ? I2C_BYTE_INDEX : (client->
-+ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+ : I2C_HALF_WORD_BIG_ENDIAN));
-+#endif
-+ priv->config.databuffer = data;
-+ priv->config.count_data = count;
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ priv->config.multi_operation = NOMADIK_TRUE;
-+ /* Do the write */
-+ priv->config.operation = I2C_WRITE;
-+
-+ if (i2c_initialize(priv)) {
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ if (verify_parameters(priv)) {
-+ error("Error in parameters\n");
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ retval = write_i2c(priv);
-+
-+ if (retval) {
-+ error("Error in write_register: %d\n", retval);
-+ } else if (retval == 0) {
-+
-+ if (priv->config.data_transfer_mode !=
-+ I2C_TRANSFER_MODE_POLLING) {
-+ retval = nomadik_i2c_wait_msg(priv, count);
-+ if (retval) {
-+ error
-+ ("Message timeout with no handled event\n");
-+ error("error waiting for i2c read: %d\n",
-+ retval);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return retval;
-+ }
-+ }
-+ else mdelay(1);
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ up(&nomadik_i2c[bus_id].lock);
-+ return retval;
-+ }
-+
-+ up(&nomadik_i2c[bus_id].lock);
-+
-+ /* Neither register mode for this client, return an error */
-+ return -EINVAL;
-+}
-+
-+/**
-+ * nomadik_i2c_read_register - Read data from I2C client
-+ * @client_id - Identifier for the client
-+ * @data - Pointer where the read data will be written.
-+ * @index - Register index of the client
-+ * @count - Amount of data in bytes to be read
-+ *
-+ * Handle all register index type writes. Using the client structs for
-+ * the client_id, we can call the correct register write function and
-+ * ensure a two byte index has the correct byte order.
-+ * Retrive the client specific information from the client id and feed it to
-+ * the controller specific configuration. Then call the respective board
-+ * specific routine.
-+ **/
-+
-+int nomadik_i2c_read_register(__u32 client_id,
-+ __u8 * data, int index, int count)
-+{
-+ int bus_id;
-+ int retval;
-+ __u16 addr;
-+ struct nomadik_i2c_client *client;
-+ struct nomadik_i2c_private *priv;
-+
-+ if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
-+ return retval;
-+
-+ client = &priv_client[client_id];
-+ bus_id = client->bus_id;
-+ priv = &i2c_driver[bus_id];
-+ addr = client->addr;
-+
-+ if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+ return -ERESTARTSYS;
-+
-+// reset_i2c(priv);
-+
-+ /* Save parameters. */
-+ priv->config.slave_address = addr;
-+ priv->config.status = I2C_STATUS_SLAVE_MODE;
-+ priv->config.register_index = index;
-+#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
-+ priv->config.index_format =
-+ ((client->index_width ==
-+ REG8) ? I2C_BYTE_INDEX : (client->
-+ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+ : I2C_HALF_WORD_BIG_ENDIAN));
-+
-+#else
-+
-+ priv->config.index_format =
-+ ((client->index_width == 0)?I2C_NO_INDEX:
-+ (client->index_width ==
-+ REG8) ? I2C_BYTE_INDEX : (client->
-+ endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+ : I2C_HALF_WORD_BIG_ENDIAN));
-+
-+#endif
-+ priv->config.databuffer = data;
-+ priv->config.count_data = count;
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ priv->config.multi_operation = NOMADIK_TRUE;
-+ /* Do the read operation */
-+ priv->config.operation = I2C_READ;
-+
-+ if (i2c_initialize(priv)) {
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ if (verify_parameters(priv)) {
-+ error("Error in parameters\n");
-+ up(&nomadik_i2c[bus_id].lock);
-+ return -EINVAL;
-+ }
-+
-+ retval = read_i2c(priv);
-+
-+ if (retval) {
-+ error("Error in read register: %d\n", retval);
-+ } else if (retval == 0) {
-+
-+ if (priv->config.data_transfer_mode !=
-+ I2C_TRANSFER_MODE_POLLING) {
-+ retval = nomadik_i2c_wait_msg(priv, count);
-+ if (retval) {
-+ error
-+ ("Message timeout with no handled event\n");
-+ error("error waiting for i2c read: %d\n",
-+ retval);
-+ up(&nomadik_i2c[bus_id].lock);
-+ return retval;
-+ }
-+ }
-+ else mdelay(1);
-+ priv->config.active_event.type = I2C_NO_EVENT;
-+ up(&nomadik_i2c[bus_id].lock);
-+ return 0;
-+ }
-+
-+ up(&nomadik_i2c[bus_id].lock);
-+
-+ /* Neither register mode for this client, return an error */
-+ return -EINVAL;
-+}
-+
-+static unsigned int nomadik_i2c_func(struct i2c_adapter *adap)
-+{
-+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK;
-+ //return I2C_FUNC_I2C;
-+}
-+
-+static int nomadik_i2c_remove(struct platform_device *pdev)
-+{
-+
-+ int retval;
-+ i2c_del_adapter(&nomadik_i2c[pdev->id]);
-+
-+ free_irq(i2c_driver[pdev->id].irq, &i2c_driver[pdev->id]);
-+
-+ disable_i2c(&i2c_driver[pdev->id]);
-+
-+ retval =
-+ nomadik_gpio_altfuncdisable(GPIO_ALT_I2C_0 + pdev->id, (char *)pdev->name);
-+ if (retval) {
-+ error("GPIO Disable Alt Function(%d) failed with %d\n",
-+ pdev->id, retval);
-+ return retval;
-+ }
-+
-+ return 0;
-+}
-+
-+static int nomadik_i2c_probe(struct platform_device *pdev)
-+{
-+ int irq;
-+ int retval = -EINVAL;
-+ struct resource *res = NULL;
-+
-+ /*Fetch the Resources, using platform data */
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (NULL == res) {
-+ dev_err(&pdev->dev, "probe - MEM resources not defined\n");
-+ return -ENODEV;
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(&pdev->dev, "probe - IRQ resource not defined\n");
-+ return -ENODEV;
-+ }
-+
-+ i2c_driver[pdev->id].regs = (void *)IO_ADDRESS(res->start);
-+ i2c_driver[pdev->id].id = pdev->id;
-+ i2c_driver[pdev->id].irq = irq;
-+ i2c_driver[pdev->id].adap = &nomadik_i2c[pdev->id];
-+
-+ nomadik_i2c[pdev->id].data = (void *)&i2c_driver[pdev->id];
-+ nomadik_i2c[pdev->id].dev.parent = &pdev->dev;
-+
-+ retval = i2c_add_adapter(&nomadik_i2c[pdev->id]);
-+ if (retval) {
-+ error("Nomadik I2C[%d] Error: failed to add adapter\n",
-+ pdev->id);
-+ return retval;
-+ }
-+
-+ /* Initialize semaphores */
-+ sema_init(&nomadik_i2c[pdev->id].lock, 1);
-+
-+ retval = request_irq(i2c_driver[pdev->id].irq,
-+ nomadik_i2c_irq_handler,
-+ 0,
-+ nomadik_i2c[pdev->id].name, &i2c_driver[pdev->id]);
-+ if (retval < 0) {
-+ error("i2c[%d] can't get requested irq %d\n",
-+ pdev->id, i2c_driver[pdev->id].irq);
-+ return retval;
-+ }
-+
-+ if (pdev->id == 0) {
-+ retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
-+ if (retval) {
-+ error
-+ ("GPIO Enable Alt Function(%d) failed with return = %d\n",
-+ pdev->id, retval);
-+ return (-EIO);
-+ }
-+ } else {/*
-+ retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_1, "I2C_1");
-+ if (retval) {
-+ error
-+ ("GPIO Enable Alt Function(%d) failed with return = %d\n",
-+ pdev->id, retval);
-+ return (-EIO);
-+ }*/
-+ }
-+ init_waitqueue_head(&i2c_driver[pdev->id].event_wq);
-+ reset_i2c(&i2c_driver[pdev->id]);
-+ return 0;
-+}
-+
-+static struct platform_driver nomadik_i2c_driver = {
-+ .probe = nomadik_i2c_probe,
-+ .remove = nomadik_i2c_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "NOMADIK-I2C",
-+ },
-+};
-+
-+static int __init i2c_nomadik_init(void)
-+{
-+ return platform_driver_register(&nomadik_i2c_driver);
-+}
-+
-+static void __exit i2c_nomadik_exit(void)
-+{
-+ platform_driver_unregister(&nomadik_i2c_driver);
-+ return;
-+}
-+
-+EXPORT_SYMBOL(nomadik_i2c_get_info);
-+EXPORT_SYMBOL(nomadik_i2c_is_busy);
-+EXPORT_SYMBOL(nomadik_i2c_read_register);
-+EXPORT_SYMBOL(nomadik_i2c_write_register);
-+EXPORT_SYMBOL(nomadik_i2c_get_client);
-+
-+module_init(i2c_nomadik_init);
-+module_exit(i2c_nomadik_exit);
-+
-+MODULE_DESCRIPTION("Nomadik IIC driver v" DRIVER_VERSION);
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h
---- linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h 2008-07-04 23:45:14.000000000 +0530
-@@ -0,0 +1,93 @@
-+/* drivers/i2c/busses/i2c-nomadik.h
-+ *
-+ * This is the non-public header file for the nomadik i2c driver.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ */
-+
-+#ifndef I2C_NOMADIC_PRIV_HEADER
-+#define I2C_NOMADIC_PRIV_HEADER
-+
-+#ifndef _NOMADIK_DEFS_H
-+#include <asm/arch/defs.h>
-+#endif
-+
-+#ifndef I2C_NOMADIC_HEADER
-+#include <asm/arch/i2c.h>
-+#endif
-+
-+#define I2C_ALGO_NOMADIK 0x15000000
-+#define I2C_HW_NOMADIK 0x01
-+#define I2C_DRIVERID_NOMADIK 0xF000
-+
-+#define I2C0_IOSIZE 0x00000FFF
-+#define I2C1_IOSIZE 0x00000FFF
-+
-+#define MSG_WAIT_USEC 500 // Wait 500 uSecs to test active event again.
-+#define MAX_WIAT_TIMEOUTS 100
-+
-+/***
-+ * Other structs
-+ ***/
-+struct nomadik_i2c_client {
-+ __u32 id;
-+ __u32 bus_id;
-+ __u8 addr;
-+ __u8 endianness; // This indicates endianness of device's register index
-+ __u8 index_width; // 8 or 16 bits;
-+};
-+
-+#define BIG_END 0
-+#define LITTLE_END 1
-+#define REG8 8
-+#define REG16 16
-+
-+struct nomadik_i2c_private {
-+ __u32 id; // bus id
-+ struct i2c_adapter *adap;
-+ int irq;
-+ struct semaphore sema; // Use for blocking on aa message completion
-+ int fast_mode;
-+ void __iomem *regs;
-+ wait_queue_head_t event_wq;
-+ struct i2c_controller_config config;
-+};
-+
-+static inline int nomadik_i2c_check_client_id(__u32 id)
-+{
-+ if ((id < 0) || (id >= I2C_NUM_CLIENTS)) {
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ Configuration functions
-+-----------------------------------------------------------------------------*/
-+int setup_i2c_controller(struct nomadik_i2c_private *priv);
-+
-+int write_i2c(struct nomadik_i2c_private *priv);
-+
-+int read_i2c(struct nomadik_i2c_private *priv);
-+
-+int process_interrupt(struct nomadik_i2c_private *priv);
-+int verify_parameters(struct nomadik_i2c_private *priv);
-+void reset_i2c(struct nomadik_i2c_private *priv);
-+void disable_i2c(struct nomadik_i2c_private *priv);
-+void stn_cut_mdelay(int dlytime);
-+
-+#endif
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c
---- linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c 2008-07-04 23:45:14.000000000 +0530
-@@ -0,0 +1,1723 @@
-+
-+/* drivers/i2c/busses/i2c-nmdk8810.c
-+ *
-+ * Support for i2c bus on STn8810 (Nomadik) chips.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Melwyn LOBO <melwyn.lobo@st.com>
-+ *-----------------------------------------------------------------------------
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+
-+#include "i2c-nomadik.h"
-+#include <linux/delay.h>
-+
-+#define I2C_ENDAD_COUNTER 50000
-+#define I2C_INT_ENDED_COUNTER 50000
-+#define I2C_BTF_COUNTER 50000
-+#define I2C_BTF_COUNTER_POLLING 50000
-+#define I2C_FIFO_FLUSH_COUNTER 500
-+#define I2C_LOWER_SLAVE 127
-+#define I2C_UPPER_SLAVE 1024
-+
-+/*#######################################################################
-+ Macros to access I2C Registers with their offsets
-+#########################################################################
-+*/
-+
-+#define I2C_REG_OFFSET_CR 0x00
-+#define I2C_REG_OFFSET_SR1 0x04
-+#define I2C_REG_OFFSET_SR2 0x08
-+#define I2C_REG_OFFSET_CCR 0x0C
-+#define I2C_REG_OFFSET_OAR1 0x10
-+#define I2C_REG_OFFSET_OAR2 0x14
-+#define I2C_REG_OFFSET_DR 0x18
-+#define I2C_REG_OFFSET_ECCR 0x1C
-+
-+/*#######################################################################
-+ Macros to access I2C Interrupt Registers event
-+#########################################################################
-+*/
-+
-+#define I2C0_IRQ_SRC_ALL 0
-+#define I2C1_IRQ_SRC_ALL 1
-+
-+#define I2C_IT_BTF STD_MASK_BIT0
-+#define I2C_IT_ADSL STD_MASK_BIT1
-+#define I2C_IT_SB STD_MASK_BIT2
-+#define I2C_IT_AF STD_MASK_BIT3
-+#define I2C_IT_STOPF STD_MASK_BIT4
-+#define I2C_IT_ARLO STD_MASK_BIT5
-+#define I2C_IT_BERR STD_MASK_BIT6
-+#define I2C_IT_ADD10 STD_MASK_BIT7
-+#define I2C_IT_SCLFAL STD_MASK_BIT8
-+#define I2C_IT_ENDAD STD_MASK_BIT9
-+
-+/*#######################################################################
-+ I2C Control Register
-+#########################################################################
-+*/
-+
-+#define I2C_ITE STD_MASK_BIT0
-+#define I2C_STOP STD_MASK_BIT1
-+#define I2C_ACK STD_MASK_BIT2
-+#define I2C_START STD_MASK_BIT3
-+#define I2C_ENGC STD_MASK_BIT4
-+#define I2C_PE STD_MASK_BIT5
-+#define I2C_TRANS STD_MASK_BIT6
-+#define I2C_DDC1EN STD_MASK_BIT7
-+#define I2C_SHIFT_ITE 0
-+#define I2C_SHIFT_STOP 1
-+#define I2C_SHIFT_ACK 2
-+#define I2C_SHIFT_START 3
-+#define I2C_SHIFT_ENGC 4
-+#define I2C_SHIFT_PE 5
-+#define I2C_SHIFT_TRANS 6
-+#define I2C_SHIFT_DDC1EN 7
-+
-+/*#######################################################################
-+ I2C Status Register1
-+#########################################################################
-+*/
-+
-+#define I2C_SB STD_MASK_BIT0
-+#define I2C_MASTER STD_MASK_BIT1
-+#define I2C_ADSL STD_MASK_BIT2
-+#define I2C_BTF STD_MASK_BIT3
-+#define I2C_BUSY STD_MASK_BIT4
-+#define I2C_TRA STD_MASK_BIT5
-+#define I2C_ADD10 STD_MASK_BIT6
-+#define I2C_EVF STD_MASK_BIT7
-+#define I2C_SHIFT_SB 0
-+#define I2C_SHIFT_MASTER 1
-+#define I2C_SHIFT_ADSL 2
-+#define I2C_SHIFT_BTF 3
-+#define I2C_SHIFT_BUSY 4
-+#define I2C_SHIFT_TRA 5
-+#define I2C_SHIFT_ADD10 6
-+#define I2C_SHIFT_EVF 7
-+
-+/*#######################################################################
-+ I2C Status Register2
-+#########################################################################
-+*/
-+
-+#define I2C_GCAL STD_MASK_BIT0
-+#define I2C_BERR STD_MASK_BIT1
-+#define I2C_ARLO STD_MASK_BIT2
-+#define I2C_STOPF STD_MASK_BIT3
-+#define I2C_AF STD_MASK_BIT4
-+#define I2C_ENDAD STD_MASK_BIT5
-+#define I2C_SCLFAL STD_MASK_BIT7
-+#define I2C_SHIFT_GCAL 0
-+#define I2C_SHIFT_BERR 1
-+#define I2C_SHIFT_ARLO 2
-+#define I2C_SHIFT_STOPF 3
-+#define I2C_SHIFT_AF 4
-+#define I2C_SHIFT_ENDAD 5
-+#define I2C_SHIFT_SCLFAL 7
-+
-+/*#######################################################################
-+ I2C Clock Control Register
-+#########################################################################
-+*/
-+
-+#define I2C_CLOCK_MASK 0x7F
-+#define I2C_FM_SM_MASK 0x80
-+
-+/*#######################################################################
-+ Default I2C Register Values
-+#########################################################################
-+*/
-+
-+#define DEFAULT_CR_REG (GEN_MASK(0UL,I2C_ENGC,I2C_SHIFT_ENGC) | \
-+ GEN_MASK(0UL,I2C_DDC1EN,I2C_SHIFT_DDC1EN) \
-+ )
++#define DEFAULT_CR_REG (GEN_MASK(0UL,I2C_ENGC,I2C_SHIFT_ENGC) | \
++ GEN_MASK(0UL,I2C_DDC1EN,I2C_SHIFT_DDC1EN) \
++ )
+
+#define DEFAULT_OAR1_REG(address) ( GEN_MASK(((address)<<1),0xFF,0) \
+ )
+ 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);
+ 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;
+ (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) {
+ i2c_abort(priv);
+ return -EIO;
+ }
-+ }
++ }
+ }
+ if ((I2C_READ == priv->config.operation)
+ && (priv->config.slave_address < 1024
+
+ switch (priv->config.index_transfer_mode) {
+ case I2C_TRANSFER_MODE_POLLING:
-+ /*
++ /*
+ Index Transfer
+ */
+ if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
+
+ switch (priv->config.index_transfer_mode) {
+ case I2C_TRANSFER_MODE_POLLING:
-+ /*
++ /*
+ Index Transfer
+ */
+ if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
+ 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);
+
+ }
+ }
-+ }
++ }
+ else if (I2C_STATUS_MASTER_RECEIVER_MODE ==
+ priv->config.status) {
+ switch (priv->config.index_format) {
+ } /*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) {
+}
+
+
-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
+#define I2C_INT_SHIFT_BERR 25
+
+/*#######################################################################
-+ Default I2C Register Values
++ Default I2C Register Values
+#########################################################################
+ */
+
+#define READ_FIELD(reg_name,mask,shift) ((reg_name & mask) >> shift )
+
+/*#######################################################################
-+ Defines used various operations
++ Defines used various operations
+#########################################################################
+*/
+#define I2C_ENDAD_COUNTER 50000
+ priv->config.transfer_data++;
+ priv->config.count_data--;
+ priv->config.active_event.type = I2C_DATA_RX_EVENT;
-+ }
++ }
+
+ loop_counter = 0;
+ if (loop_till_set
+ priv->config.transfer_data++;
+ priv->config.count_data--;
+ priv->config.active_event.type = I2C_DATA_RX_EVENT;
-+ }
++ }
+
+ loop_counter = 0;
+ if (loop_till_set
+ 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) {
+ int error_status = 0;
+
+ case I2C_TRANSFER_MODE_POLLING:
-+ /*
++ /*
+ Index Transfer
+ */
+ if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
+ 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) {
+
+ default:
+ break;
-+ }
++ }
+
+ priv->config.active_event.id = priv->id;
+ priv->config.active_event.transfer_data = priv->config.transfer_data;
+}
+
+
-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 @@
+
+/*
+ *
+ * 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
+ * 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)
+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);
/**
* 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
+ 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
+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
+{
+#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);
+{
+#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);
+ schedule_delayed_work(&kp->kscan_work, KEYPAD_SCAN_PERIOD);
+ nmdk_info("Keypad polling started");
+ }
-+
++
+
+#endif
+ nmdk_info("Module initialized Ver(%d.%d.%d)",
+
+ 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
+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.
+ 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.
#
# 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
+obj-$(CONFIG_TOUCHSCREEN_NOMADIK_TS2003) += touchp2003-nomadik.o
+
+nmdkmod_tp-objs := touchp-nomadik.o
-diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c ../new/linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c
---- linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c 2008-07-04 23:45:18.000000000 +0530
-@@ -0,0 +1,566 @@
-+/*
-+ * linux/drivers/i2c/chips/tsc2003.c
-+ *
-+ * Copyright (C) 2005 Bill Gatliff <bgat at billgatliff.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Driver for TI's TSC2003 I2C Touch Screen Controller
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/i2c.h>
-+#include <linux/string.h>
-+#include <linux/bcd.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <asm/arch/touchp2003.h>
-+#include <asm/arch/i2c.h>
-+
-+#define DEBUG_TS(x) printk x
-+
-+/*
-+ * Insmod parameters
-+ */
-+
-+#define DRIVER_NAME "tsc2003"
-+
-+enum tsc2003_pd {
-+ PD_POWERDOWN = 0, /* penirq */
-+ PD_IREFOFF_ADCON = 1, /* no penirq */
-+ PD_IREFON_ADCOFF = 2, /* penirq */
-+ PD_IREFON_ADCON = 3, /* no penirq */
-+ PD_PENIRQ_ARM = PD_IREFON_ADCOFF,
-+ PD_PENIRQ_DISARM = PD_IREFON_ADCON,
-+};
-+
-+enum tsc2003_m {
-+ M_12BIT = 0,
-+ M_8BIT = 1
-+};
-+
-+enum tsc2003_cmd {
-+ MEAS_TEMP0 = 0,
-+ MEAS_VBAT1 = 1,
-+ MEAS_IN1 = 2,
-+ MEAS_TEMP1 = 4,
-+ MEAS_VBAT2 = 5,
-+ MEAS_IN2 = 6,
-+ ACTIVATE_NX_DRIVERS = 8,
-+ ACTIVATE_NY_DRIVERS = 9,
-+ ACTIVATE_YNX_DRIVERS = 10,
-+ MEAS_XPOS = 12,
-+ MEAS_YPOS = 13,
-+ MEAS_Z1POS = 14,
-+ MEAS_Z2POS = 15
-+};
-+
-+#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1))
-+
-+#define ADC_MAX ((1 << 12) - 1)
-+
-+struct tsc2003_data {
-+ struct i2c_client client;
-+
-+ /*struct device_driver driver; FRED*/
-+ struct platform_driver driver;
-+ struct touchp_tsc2003_device * board;
-+
-+ struct input_dev idev;
-+ struct timer_list penirq_timer;
-+ struct semaphore sem;
-+ int is_opened;
-+ enum tsc2003_pd pd;
-+ enum tsc2003_m m;
-+ int penirq;
-+ struct work_struct workq;
-+ int vbat1;
-+ int vbat2;
-+ int temp0;
-+ int temp1;
-+ int in1;
-+ int in2;
-+};
-+
-+static void ReactivatePenIRQ (struct tsc2003_data *data);
-+static void tsc2003ts_task (void *v);
-+
-+static inline int tsc2003_command (struct tsc2003_data *data,
-+ enum tsc2003_cmd cmd,
-+ enum tsc2003_pd pd)
-+{
-+ char c;
-+ int ret;
-+ //down(&data->sem);
-+ c = TSC2003_CMD(cmd, pd, data->m);
-+ //ret = i2c_master_send(&data->client, &c, 1);
-+ ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
-+
-+ //up(&data->sem);
-+ return ret;
-+}
-+
-+static int tsc2003_read (struct tsc2003_data *data,
-+ enum tsc2003_cmd cmd,
-+ enum tsc2003_pd pd,
-+ int *val)
-+{
-+ char c;
-+ char d_read[2];
-+ int ret;
-+
-+ c = TSC2003_CMD(cmd, pd, data->m);
-+ //ret = i2c_master_send(&data->client, &c, 1);
-+ ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
-+ if (ret) goto err;
-+
-+ udelay(20);
-+ //ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1);
-+ ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
-+ if (ret) goto err;
-+
-+ if (val)
-+ {
-+ *val = d_read[0];
-+ *val <<= 4;
-+ if (data->m == M_12BIT)
-+ *val += (d_read[1] >> 4);
-+ }
-+
-+#if defined(CONFIG_I2C_DEBUG_CHIP)
-+ printk(KERN_ERR "%s: val[%x] = %d\n",
-+ __FUNCTION__, cmd, (((int)d_read[0]) << 8) + d_read[1]);
-+#endif
-+
-+ return 0;
-+ err:
-+ if (!ret) ret = -ENODEV;
-+ return ret;
-+}
-+
-+static int send_command (struct tsc2003_data *data,
-+ unsigned char command_byte, unsigned short *val)
-+{
-+ char d_read[2];
-+ int ret;
-+
-+ ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&command_byte,0,1);
-+ if (ret) goto err;
-+
-+ udelay(20);
-+ ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
-+ if (ret) goto err;
-+
-+ if (val)
-+ {
-+ *val = d_read[0];
-+ *val <<= 4;
-+ if (data->m == M_12BIT)
-+ *val += (d_read[1] >> 4);
-+ }
-+
-+ return 0;
-+ err:
-+ if (!ret) ret = -ENODEV;
-+ return ret;
-+}
-+
-+static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+ return tsc2003_read(d, MEAS_TEMP0, pd, t);
-+}
-+
-+static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+ return tsc2003_read(d, MEAS_TEMP1, pd, t);
-+}
-+
-+static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *x)
-+{
-+ return tsc2003_read(d, MEAS_XPOS, pd, x);
-+}
-+
-+static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *y)
-+{
-+ return tsc2003_read(d, MEAS_YPOS, pd, y);
-+}
-+
-+static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *p)
-+{
-+ return tsc2003_read(d, MEAS_Z1POS, pd, p);
-+}
-+
-+static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+ return tsc2003_read(d, MEAS_IN1, pd, t);
-+}
-+
-+static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+ return tsc2003_read(d, MEAS_IN2, pd, t);
-+}
-+
-+static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+ return tsc2003_read(d, MEAS_VBAT1, pd, t);
-+}
-+
-+static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+ return tsc2003_read(d, MEAS_VBAT2, pd, t);
-+}
-+
-+static inline int tsc2003_powerdown (struct tsc2003_data *d)
-+{
-+ /* we don't have a distinct powerdown command,
-+ so do a benign read with the PD bits cleared */
-+ return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0);
-+}
-+
-+
-+#define PENUP_TIMEOUT 50 /* msec */
-+
-+/*static irqreturn_t tsc2003_penirq (int irq, void *v, struct pt_regs *regs)
-+{
-+ struct tsc2003_data *d = v;
-+ DEBUG_TS(("tsc2003_penirq\n"));
-+ complete(&d->penirq_completion);
-+ return IRQ_HANDLED;
-+}*/
-+
-+/* Fred : replaced by callback */
-+static void ts2003_callback (void * parameter)
-+{
-+ struct tsc2003_data *d = (struct tsc2003_data *)parameter;
-+ //DEBUG_TS(("ts2003_callback\n"));
-+
-+ tsc2003ts_task(d);
-+}
-+
-+static int tsc2003_remove(struct platform_device *pdev)
-+{
-+ struct tsc2003_data *data;
-+
-+ data = platform_get_drvdata(pdev);
-+ //input_free_device(&data->idev);
-+ input_unregister_device(&data->idev);
-+ kfree(data);
-+
-+ return 0;
-+}
-+
-+static inline void tsc2003_restart_pen_up_timer (struct tsc2003_data *d)
-+{
-+ mod_timer(&d->penirq_timer, jiffies + (PENUP_TIMEOUT * HZ) / 1000);
-+}
-+
-+
-+static void tsc2003_timer_callback (unsigned long v)
-+{
-+ struct tsc2003_data *d = (struct tsc2003_data *)v;
-+ schedule_work(&d->workq);
-+}
-+
-+static void tsc2003_timer_callback1(struct work_struct *work)
-+{
-+ /*struct tsc2003_data *d = (struct tsc2003_data *)v;*/
-+ struct tsc2003_data *d = container_of(work, struct tsc2003_data, workq);
-+ unsigned char pin_value ;
-+ unsigned int x, y, p;
-+
-+ struct task_struct *tsk = current;
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+
-+ d->board->pirq_read_val(&pin_value);
-+ if( pin_value == 1)
-+ {
-+ /* The pen is up */
-+ /*printk("pen is up....\n"); */
-+ input_report_abs(&d->idev, ABS_PRESSURE, 0);
-+ input_sync(&d->idev);
-+ /*schedule_timeout(HZ/20);*/
-+ return ;
-+ }
-+
-+ tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
-+ tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
-+ tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
-+ ReactivatePenIRQ(d);
-+
-+ input_report_abs(&d->idev, ABS_X, x);
-+ input_report_abs(&d->idev, ABS_Y, y);
-+ input_report_abs(&d->idev, ABS_PRESSURE, p);
-+ input_sync(&d->idev);
-+
-+ /*d->board->pirq_read_val(&pin_value); */
-+ if( pin_value == 0)
-+ {
-+ /* pen down event, (re)start the pen up timer */
-+ tsc2003_restart_pen_up_timer(d);
-+ }
-+#if 0
-+ else
-+ {
-+ /* The pen is up */
-+ /*printk("pen is up again ....\n");*/
-+ input_report_abs(&d->idev, ABS_PRESSURE, 0);
-+ input_sync(&d->idev);
-+ /*schedule_timeout(HZ/20); */
-+ }
-+#endif
-+ return;
-+}
-+
-+static void ReactivatePenIRQ (struct tsc2003_data *data)
-+{
-+ unsigned char command_byte;
-+ unsigned short dummy ;
-+
-+ /* Send I2C command to reactivate PENIRQn */
-+ /* C3=1, C2=1, C1=0, C0=0, PD1=0, PD2=0, M=0 */
-+ command_byte = 0xC0;
-+ send_command(data, command_byte, &dummy);
-+
-+ // acknowledge possible pending interrupt
-+ //data->board->pirq_ack();
-+}
-+
-+static void tsc2003ts_task (void *v)
-+{
-+ struct tsc2003_data *d = v;
-+ unsigned int x, y, p;
-+
-+ tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
-+ tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
-+ tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
-+ ReactivatePenIRQ(d);
-+
-+ input_report_abs(&d->idev, ABS_X, x);
-+ input_report_abs(&d->idev, ABS_Y, y);
-+ input_report_abs(&d->idev, ABS_PRESSURE, p);
-+ input_sync(&d->idev);
-+
-+ /* pen down event, (re)start the pen up timer */
-+ tsc2003_restart_pen_up_timer(d);
-+
-+ d->board->pirq_ack();
-+ d->board->pirq_en();
-+}
-+
-+static int tsc2003_idev_open (struct input_dev *i_dev)
-+{
-+ struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
-+ int ret = 0;
-+
-+ DEBUG_TS(("tsc2003_idev_open\n"));
-+ if (down_interruptible(&d->sem))
-+ return -EINTR;
-+
-+ if (d->is_opened)
-+ panic(DRIVER_NAME "tsd already running (!). abort.");
-+
-+ if (d->board->irq_init)
-+ {
-+ if (d->board->irq_init(ts2003_callback,(void*)d))
-+ {
-+ return -1;
-+ }
-+ d->board->pirq_en();
-+ }
-+ DEBUG_TS(("\tcallback setup\n"));
-+ d->penirq_timer.data = (unsigned long)d;
-+ d->penirq_timer.function = tsc2003_timer_callback;
-+
-+ d->is_opened = 1 ;
-+ up(&d->sem);
-+
-+ return 0;
-+}
-+
-+static void tsc2003_idev_close (struct input_dev *i_dev)
-+{
-+ struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
-+ DEBUG_TS(("tsc2003_idev_close\n"));
-+ down_interruptible(&d->sem);
-+
-+ d->is_opened = 0 ;
-+ //free_irq(d->penirq, d);
-+ if (d->board->irq_exit)
-+ {
-+ d->board->irq_exit();
-+ }
-+
-+ if (timer_pending(&d->penirq_timer))
-+ del_timer(&d->penirq_timer);
-+
-+ up(&d->sem);
-+ return;
-+}
-+
-+static int tsc2003_driver_register (struct tsc2003_data *data)
-+{
-+ int ret = 0;
-+ DEBUG_TS(("tsc2003_driver_register\n"));
-+
-+ init_MUTEX(&data->sem);
-+ init_timer(&data->penirq_timer);
-+ data->is_opened = 0 ;
-+ data->penirq_timer.data = (unsigned long)data;
-+ data->penirq_timer.function = tsc2003_timer_callback;
-+
-+INIT_WORK(&data->workq, tsc2003_timer_callback1);
-+
-+ //init_input_dev(&data->idev);
-+ init_ts_input_dev(&data->idev);
-+ data->idev.name = DRIVER_NAME;
-+ data->idev.evbit[0] = BIT(EV_ABS);
-+ data->idev.open = tsc2003_idev_open;
-+ data->idev.close = tsc2003_idev_close;
-+ data->idev.absbit[LONG(ABS_X)] = BIT(ABS_X);
-+ data->idev.absbit[LONG(ABS_Y)] = BIT(ABS_Y);
-+ data->idev.absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE);
-+
-+ input_set_abs_params(&data->idev, ABS_X, 0, ADC_MAX, 0, 0);
-+ input_set_abs_params(&data->idev, ABS_Y, 0, ADC_MAX, 0, 0);
-+
-+ ret = input_register_device(&data->idev);
-+
-+ return ret;
-+}
-+
-+
-+static int __init tsc2003_probe(struct platform_device *pdev)
-+{
-+ struct tsc2003_data *d;
-+ int err;
-+ struct touchp_tsc2003_device *touchp_board = pdev->dev.platform_data;
-+
-+ DEBUG_TS(("tsc2003_probe\n"));
-+
-+ d = kcalloc(1, sizeof(*d), GFP_KERNEL);
-+ if (!d)
-+ {
-+ err = -ENOMEM;
-+ goto err_kzalloc;
-+ }
-+
-+ DEBUG_TS(("\tdata allocated(%x)\n",(unsigned int)d));
-+ platform_set_drvdata(pdev, d);
-+ d = platform_get_drvdata(pdev);
-+
-+ if (!touchp_board) {
-+ printk("touchp platform data not defined");
-+ err = -1;
-+ goto err_board;
-+ }
-+ d->board = touchp_board;
-+
-+ DEBUG_TS(("Probing TSC2003\n"));
-+ err = tsc2003_powerdown(d);
-+ if (err >= 0)
-+ {
-+ DEBUG_TS(("\tpowerdown ok\n"));
-+ d->pd = PD_PENIRQ_DISARM;
-+ d->m = M_8BIT;
-+ err = tsc2003_driver_register(d);
-+ if (err) {
-+ goto err_init_tsc2003;
-+ }
-+ printk("\tTSC2003 Module initialized\n");
-+ return 0;
-+ }
-+
-+ err_init_tsc2003:
-+ err_board:
-+ kfree(d);
-+ err_kzalloc:
-+ return err;
-+}
-+
-+#ifdef CONFIG_PM
-+int nomadik_tsc2003_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+#if 0
-+ struct tsc2003_data *d = platform_get_drvdata(pdev);
-+
-+ if (d->board->pirq_en) {
-+ /*printk("touchscreen suspend: enabling interrupt...\n");*/
-+ d->board->pirq_en();
-+ }
-+
-+ if ( !device_may_wakeup(&pdev->dev) )
-+ if (d->board->pirq_dis) {
-+ /*printk("touchscreen suspend: disabling interrupt...\n");*/
-+ d->board->pirq_dis();
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int nomadik_tsc2003_resume(struct platform_device *pdev)
-+{
-+#if 0
-+ struct tsc2003_data *d = platform_get_drvdata(pdev);
-+
-+ if (d->board->pirq_dis) {
-+ /*printk("touchscreen resume: disabling interrupt...\n");*/
-+ d->board->pirq_dis();
-+ }
-+
-+ if ( !device_may_wakeup(&pdev->dev) )
-+ if (d->board->pirq_en) {
-+ /*printk("touchscreen resume: enabling interrupt...\n");*/
-+ d->board->pirq_en();
-+ }
-+#endif
-+ return 0;
-+}
-+
-+#else
-+#define nomadik_tsc2003_suspend NULL
-+#define nomadik_tsc2003_resume NULL
-+#endif /* CONFIG_PM */
-+
-+static struct platform_driver tsc2003_driver = {
-+ .probe = tsc2003_probe,
-+ .remove = tsc2003_remove,
-+ .driver = {
-+ .name = "tsc2003",
-+ },
-+ .suspend = nomadik_tsc2003_suspend,
-+ .resume = nomadik_tsc2003_resume,
-+};
-+
-+static int __devinit tsc2003_init(void)
-+{
-+ return platform_driver_register(&tsc2003_driver);
-+}
-+
-+static void __exit tsc2003_exit(void)
-+{
-+ platform_driver_unregister(&tsc2003_driver);
-+}
-+
-+MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>");
-+MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver");
-+MODULE_LICENSE("GPL");
-+
-+module_init(tsc2003_init);
-+module_exit(tsc2003_exit);
-diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c
---- linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c 2008-07-04 23:45:19.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c
@@ -0,0 +1,755 @@
+/*
+ * drivers/misc/touchp-nomadik.c
+ * 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
+ */
+
+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
+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)
+/**
+ * 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)
+/**
+ * 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)
+/**
+ * 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)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+// t_bool pen_down = TRUE;
-+
++
+ nmdk_dbg_ftrace();
+
+ daemonize("touchpanel");
+ /* 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)) {
+ 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;
+
+/**
+ * nomadik_tp_init - initializes the module
-+ *
++ *
+ * This function registers and initializes the module.
+ * RETURN: Zero or negative nmdk_error code
+ */
+ }
+ 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..");
+ }
+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;
+}
+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)
+ ("Prafulla Wadaskar <prafulla.wadaskar@st.com>, ST Microelectronics");
+MODULE_DESCRIPTION("Nomadik Touchpanel Driver");
+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/Makefile ../new/linux-2.6.20/drivers/Makefile
---- linux-2.6.20/drivers/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -5,6 +5,7 @@
- # Rewritten to use lists instead of if-statements.
- #
+--- /dev/null
++++ linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c
+@@ -0,0 +1,566 @@
++/*
++ * linux/drivers/i2c/chips/tsc2003.c
++ *
++ * Copyright (C) 2005 Bill Gatliff <bgat at billgatliff.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Driver for TI's TSC2003 I2C Touch Screen Controller
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/string.h>
++#include <linux/bcd.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <asm/arch/touchp2003.h>
++#include <asm/arch/i2c.h>
++
++#define DEBUG_TS(x) printk x
++
++/*
++ * Insmod parameters
++ */
++
++#define DRIVER_NAME "tsc2003"
++
++enum tsc2003_pd {
++ PD_POWERDOWN = 0, /* penirq */
++ PD_IREFOFF_ADCON = 1, /* no penirq */
++ PD_IREFON_ADCOFF = 2, /* penirq */
++ PD_IREFON_ADCON = 3, /* no penirq */
++ PD_PENIRQ_ARM = PD_IREFON_ADCOFF,
++ PD_PENIRQ_DISARM = PD_IREFON_ADCON,
++};
++
++enum tsc2003_m {
++ M_12BIT = 0,
++ M_8BIT = 1
++};
++
++enum tsc2003_cmd {
++ MEAS_TEMP0 = 0,
++ MEAS_VBAT1 = 1,
++ MEAS_IN1 = 2,
++ MEAS_TEMP1 = 4,
++ MEAS_VBAT2 = 5,
++ MEAS_IN2 = 6,
++ ACTIVATE_NX_DRIVERS = 8,
++ ACTIVATE_NY_DRIVERS = 9,
++ ACTIVATE_YNX_DRIVERS = 10,
++ MEAS_XPOS = 12,
++ MEAS_YPOS = 13,
++ MEAS_Z1POS = 14,
++ MEAS_Z2POS = 15
++};
++
++#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1))
++
++#define ADC_MAX ((1 << 12) - 1)
++
++struct tsc2003_data {
++ struct i2c_client client;
++
++ /*struct device_driver driver; FRED*/
++ struct platform_driver driver;
++ struct touchp_tsc2003_device * board;
++
++ struct input_dev idev;
++ struct timer_list penirq_timer;
++ struct semaphore sem;
++ int is_opened;
++ enum tsc2003_pd pd;
++ enum tsc2003_m m;
++ int penirq;
++ struct work_struct workq;
++ int vbat1;
++ int vbat2;
++ int temp0;
++ int temp1;
++ int in1;
++ int in2;
++};
++
++static void ReactivatePenIRQ (struct tsc2003_data *data);
++static void tsc2003ts_task (void *v);
++
++static inline int tsc2003_command (struct tsc2003_data *data,
++ enum tsc2003_cmd cmd,
++ enum tsc2003_pd pd)
++{
++ char c;
++ int ret;
++ //down(&data->sem);
++ c = TSC2003_CMD(cmd, pd, data->m);
++ //ret = i2c_master_send(&data->client, &c, 1);
++ ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
++
++ //up(&data->sem);
++ return ret;
++}
++
++static int tsc2003_read (struct tsc2003_data *data,
++ enum tsc2003_cmd cmd,
++ enum tsc2003_pd pd,
++ int *val)
++{
++ char c;
++ char d_read[2];
++ int ret;
++
++ c = TSC2003_CMD(cmd, pd, data->m);
++ //ret = i2c_master_send(&data->client, &c, 1);
++ ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
++ if (ret) goto err;
++
++ udelay(20);
++ //ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1);
++ ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
++ if (ret) goto err;
++
++ if (val)
++ {
++ *val = d_read[0];
++ *val <<= 4;
++ if (data->m == M_12BIT)
++ *val += (d_read[1] >> 4);
++ }
++
++#if defined(CONFIG_I2C_DEBUG_CHIP)
++ printk(KERN_ERR "%s: val[%x] = %d\n",
++ __FUNCTION__, cmd, (((int)d_read[0]) << 8) + d_read[1]);
++#endif
++
++ return 0;
++ err:
++ if (!ret) ret = -ENODEV;
++ return ret;
++}
++
++static int send_command (struct tsc2003_data *data,
++ unsigned char command_byte, unsigned short *val)
++{
++ char d_read[2];
++ int ret;
++
++ ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&command_byte,0,1);
++ if (ret) goto err;
++
++ udelay(20);
++ ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
++ if (ret) goto err;
++
++ if (val)
++ {
++ *val = d_read[0];
++ *val <<= 4;
++ if (data->m == M_12BIT)
++ *val += (d_read[1] >> 4);
++ }
++
++ return 0;
++ err:
++ if (!ret) ret = -ENODEV;
++ return ret;
++}
++
++static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++ return tsc2003_read(d, MEAS_TEMP0, pd, t);
++}
++
++static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++ return tsc2003_read(d, MEAS_TEMP1, pd, t);
++}
++
++static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *x)
++{
++ return tsc2003_read(d, MEAS_XPOS, pd, x);
++}
++
++static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *y)
++{
++ return tsc2003_read(d, MEAS_YPOS, pd, y);
++}
++
++static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *p)
++{
++ return tsc2003_read(d, MEAS_Z1POS, pd, p);
++}
++
++static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++ return tsc2003_read(d, MEAS_IN1, pd, t);
++}
++
++static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++ return tsc2003_read(d, MEAS_IN2, pd, t);
++}
++
++static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++ return tsc2003_read(d, MEAS_VBAT1, pd, t);
++}
++
++static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++ return tsc2003_read(d, MEAS_VBAT2, pd, t);
++}
++
++static inline int tsc2003_powerdown (struct tsc2003_data *d)
++{
++ /* we don't have a distinct powerdown command,
++ so do a benign read with the PD bits cleared */
++ return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0);
++}
++
++
++#define PENUP_TIMEOUT 50 /* msec */
++
++/*static irqreturn_t tsc2003_penirq (int irq, void *v, struct pt_regs *regs)
++{
++ struct tsc2003_data *d = v;
++ DEBUG_TS(("tsc2003_penirq\n"));
++ complete(&d->penirq_completion);
++ return IRQ_HANDLED;
++}*/
++
++/* Fred : replaced by callback */
++static void ts2003_callback (void * parameter)
++{
++ struct tsc2003_data *d = (struct tsc2003_data *)parameter;
++ //DEBUG_TS(("ts2003_callback\n"));
++
++ tsc2003ts_task(d);
++}
++
++static int tsc2003_remove(struct platform_device *pdev)
++{
++ struct tsc2003_data *data;
++
++ data = platform_get_drvdata(pdev);
++ //input_free_device(&data->idev);
++ input_unregister_device(&data->idev);
++ kfree(data);
++
++ return 0;
++}
++
++static inline void tsc2003_restart_pen_up_timer (struct tsc2003_data *d)
++{
++ mod_timer(&d->penirq_timer, jiffies + (PENUP_TIMEOUT * HZ) / 1000);
++}
++
++
++static void tsc2003_timer_callback (unsigned long v)
++{
++ struct tsc2003_data *d = (struct tsc2003_data *)v;
++ schedule_work(&d->workq);
++}
++
++static void tsc2003_timer_callback1(struct work_struct *work)
++{
++ /*struct tsc2003_data *d = (struct tsc2003_data *)v;*/
++ struct tsc2003_data *d = container_of(work, struct tsc2003_data, workq);
++ unsigned char pin_value ;
++ unsigned int x, y, p;
++
++ struct task_struct *tsk = current;
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ d->board->pirq_read_val(&pin_value);
++ if( pin_value == 1)
++ {
++ /* The pen is up */
++ /*printk("pen is up....\n"); */
++ input_report_abs(&d->idev, ABS_PRESSURE, 0);
++ input_sync(&d->idev);
++ /*schedule_timeout(HZ/20);*/
++ return ;
++ }
++
++ tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
++ tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
++ tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
++ ReactivatePenIRQ(d);
++
++ input_report_abs(&d->idev, ABS_X, x);
++ input_report_abs(&d->idev, ABS_Y, y);
++ input_report_abs(&d->idev, ABS_PRESSURE, p);
++ input_sync(&d->idev);
++
++ /*d->board->pirq_read_val(&pin_value); */
++ if( pin_value == 0)
++ {
++ /* pen down event, (re)start the pen up timer */
++ tsc2003_restart_pen_up_timer(d);
++ }
++#if 0
++ else
++ {
++ /* The pen is up */
++ /*printk("pen is up again ....\n");*/
++ input_report_abs(&d->idev, ABS_PRESSURE, 0);
++ input_sync(&d->idev);
++ /*schedule_timeout(HZ/20); */
++ }
++#endif
++ return;
++}
++
++static void ReactivatePenIRQ (struct tsc2003_data *data)
++{
++ unsigned char command_byte;
++ unsigned short dummy ;
++
++ /* Send I2C command to reactivate PENIRQn */
++ /* C3=1, C2=1, C1=0, C0=0, PD1=0, PD2=0, M=0 */
++ command_byte = 0xC0;
++ send_command(data, command_byte, &dummy);
++
++ // acknowledge possible pending interrupt
++ //data->board->pirq_ack();
++}
++
++static void tsc2003ts_task (void *v)
++{
++ struct tsc2003_data *d = v;
++ unsigned int x, y, p;
++
++ tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
++ tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
++ tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
++ ReactivatePenIRQ(d);
++
++ input_report_abs(&d->idev, ABS_X, x);
++ input_report_abs(&d->idev, ABS_Y, y);
++ input_report_abs(&d->idev, ABS_PRESSURE, p);
++ input_sync(&d->idev);
++
++ /* pen down event, (re)start the pen up timer */
++ tsc2003_restart_pen_up_timer(d);
++
++ d->board->pirq_ack();
++ d->board->pirq_en();
++}
++
++static int tsc2003_idev_open (struct input_dev *i_dev)
++{
++ struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
++ int ret = 0;
++
++ DEBUG_TS(("tsc2003_idev_open\n"));
++ if (down_interruptible(&d->sem))
++ return -EINTR;
++
++ if (d->is_opened)
++ panic(DRIVER_NAME "tsd already running (!). abort.");
++
++ if (d->board->irq_init)
++ {
++ if (d->board->irq_init(ts2003_callback,(void*)d))
++ {
++ return -1;
++ }
++ d->board->pirq_en();
++ }
++ DEBUG_TS(("\tcallback setup\n"));
++ d->penirq_timer.data = (unsigned long)d;
++ d->penirq_timer.function = tsc2003_timer_callback;
++
++ d->is_opened = 1 ;
++ up(&d->sem);
++
++ return 0;
++}
++
++static void tsc2003_idev_close (struct input_dev *i_dev)
++{
++ struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
++ DEBUG_TS(("tsc2003_idev_close\n"));
++ down_interruptible(&d->sem);
++
++ d->is_opened = 0 ;
++ //free_irq(d->penirq, d);
++ if (d->board->irq_exit)
++ {
++ d->board->irq_exit();
++ }
++
++ if (timer_pending(&d->penirq_timer))
++ del_timer(&d->penirq_timer);
++
++ up(&d->sem);
++ return;
++}
++
++static int tsc2003_driver_register (struct tsc2003_data *data)
++{
++ int ret = 0;
++ DEBUG_TS(("tsc2003_driver_register\n"));
++
++ init_MUTEX(&data->sem);
++ init_timer(&data->penirq_timer);
++ data->is_opened = 0 ;
++ data->penirq_timer.data = (unsigned long)data;
++ data->penirq_timer.function = tsc2003_timer_callback;
++
++INIT_WORK(&data->workq, tsc2003_timer_callback1);
++
++ //init_input_dev(&data->idev);
++ init_ts_input_dev(&data->idev);
++ data->idev.name = DRIVER_NAME;
++ data->idev.evbit[0] = BIT(EV_ABS);
++ data->idev.open = tsc2003_idev_open;
++ data->idev.close = tsc2003_idev_close;
++ data->idev.absbit[LONG(ABS_X)] = BIT(ABS_X);
++ data->idev.absbit[LONG(ABS_Y)] = BIT(ABS_Y);
++ data->idev.absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE);
++
++ input_set_abs_params(&data->idev, ABS_X, 0, ADC_MAX, 0, 0);
++ input_set_abs_params(&data->idev, ABS_Y, 0, ADC_MAX, 0, 0);
++
++ ret = input_register_device(&data->idev);
++
++ return ret;
++}
++
++
++static int __init tsc2003_probe(struct platform_device *pdev)
++{
++ struct tsc2003_data *d;
++ int err;
++ struct touchp_tsc2003_device *touchp_board = pdev->dev.platform_data;
++
++ DEBUG_TS(("tsc2003_probe\n"));
++
++ d = kcalloc(1, sizeof(*d), GFP_KERNEL);
++ if (!d)
++ {
++ err = -ENOMEM;
++ goto err_kzalloc;
++ }
++
++ DEBUG_TS(("\tdata allocated(%x)\n",(unsigned int)d));
++ platform_set_drvdata(pdev, d);
++ d = platform_get_drvdata(pdev);
++
++ if (!touchp_board) {
++ printk("touchp platform data not defined");
++ err = -1;
++ goto err_board;
++ }
++ d->board = touchp_board;
++
++ DEBUG_TS(("Probing TSC2003\n"));
++ err = tsc2003_powerdown(d);
++ if (err >= 0)
++ {
++ DEBUG_TS(("\tpowerdown ok\n"));
++ d->pd = PD_PENIRQ_DISARM;
++ d->m = M_8BIT;
++ err = tsc2003_driver_register(d);
++ if (err) {
++ goto err_init_tsc2003;
++ }
++ printk("\tTSC2003 Module initialized\n");
++ return 0;
++ }
++
++ err_init_tsc2003:
++ err_board:
++ kfree(d);
++ err_kzalloc:
++ return err;
++}
++
++#ifdef CONFIG_PM
++int nomadik_tsc2003_suspend(struct platform_device *pdev, pm_message_t state)
++{
++#if 0
++ struct tsc2003_data *d = platform_get_drvdata(pdev);
++
++ if (d->board->pirq_en) {
++ /*printk("touchscreen suspend: enabling interrupt...\n");*/
++ d->board->pirq_en();
++ }
++
++ if ( !device_may_wakeup(&pdev->dev) )
++ if (d->board->pirq_dis) {
++ /*printk("touchscreen suspend: disabling interrupt...\n");*/
++ d->board->pirq_dis();
++ }
++#endif
++ return 0;
++}
++
++int nomadik_tsc2003_resume(struct platform_device *pdev)
++{
++#if 0
++ struct tsc2003_data *d = platform_get_drvdata(pdev);
++
++ if (d->board->pirq_dis) {
++ /*printk("touchscreen resume: disabling interrupt...\n");*/
++ d->board->pirq_dis();
++ }
++
++ if ( !device_may_wakeup(&pdev->dev) )
++ if (d->board->pirq_en) {
++ /*printk("touchscreen resume: enabling interrupt...\n");*/
++ d->board->pirq_en();
++ }
++#endif
++ return 0;
++}
++
++#else
++#define nomadik_tsc2003_suspend NULL
++#define nomadik_tsc2003_resume NULL
++#endif /* CONFIG_PM */
++
++static struct platform_driver tsc2003_driver = {
++ .probe = tsc2003_probe,
++ .remove = tsc2003_remove,
++ .driver = {
++ .name = "tsc2003",
++ },
++ .suspend = nomadik_tsc2003_suspend,
++ .resume = nomadik_tsc2003_resume,
++};
++
++static int __devinit tsc2003_init(void)
++{
++ return platform_driver_register(&tsc2003_driver);
++}
++
++static void __exit tsc2003_exit(void)
++{
++ platform_driver_unregister(&tsc2003_driver);
++}
++
++MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>");
++MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver");
++MODULE_LICENSE("GPL");
++
++module_init(tsc2003_init);
++module_exit(tsc2003_exit);
+--- linux-2.6.20.orig/drivers/media/Kconfig
++++ linux-2.6.20/drivers/media/Kconfig
+@@ -63,10 +63,12 @@ source "drivers/media/radio/Kconfig"
-+obj-$(CONFIG_I2C) += i2c/
- obj-$(CONFIG_PCI) += pci/
- obj-$(CONFIG_PARISC) += parisc/
- obj-$(CONFIG_RAPIDIO) += rapidio/
-@@ -57,7 +58,6 @@ obj-$(CONFIG_GAMEPORT) += input/gamepor
- obj-$(CONFIG_INPUT) += input/
- obj-$(CONFIG_I2O) += message/
- obj-$(CONFIG_RTC_LIB) += rtc/
--obj-$(CONFIG_I2C) += i2c/
- obj-$(CONFIG_W1) += w1/
- obj-$(CONFIG_HWMON) += hwmon/
- obj-$(CONFIG_PHONE) += telephony/
-diff -Nauprw linux-2.6.20/drivers/media/Kconfig ../new/linux-2.6.20/drivers/media/Kconfig
---- linux-2.6.20/drivers/media/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/Kconfig 2008-08-12 22:56:04.000000000 +0530
-@@ -65,6 +65,8 @@ source "drivers/media/dvb/Kconfig"
+ source "drivers/media/dvb/Kconfig"
source "drivers/media/common/Kconfig"
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/
+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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 */
+/* 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. */
+#include "platform_os.h"
+
+/*-----------------------------------------------------------------------------
-+ * Type definition
++ * Type definition
+ *---------------------------------------------------------------------------*/
+typedef unsigned char t_uint8;
+typedef signed char t_sint8;
+
+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;
+
+/*
+ * 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 ,
+ HCL_FREQ_22MHZ,
+ HCL_FREQ_24MHZ,
+ HCL_FREQ_48MHZ
-+} t_frequency;
++} t_frequency;
+
+
+
+
+
+/*-----------------------------------------------------------------------------
-+ * Keyword definition
++ * Keyword definition
+ *---------------------------------------------------------------------------*/
+#define PUBLIC /* Extern by default */
+#define PRIVATE static
+#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
+#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1)
+#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2)
+#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3)
-+
++
+/*-----------------------------------------------------------------------------
+ * Halfword shift definition
+ *---------------------------------------------------------------------------*/
+ *---------------------------------------------------------------------------*/
+ #define ONE_KB (1024)
+ #define ONE_MB (ONE_KB * ONE_KB)
-+
-+
++
++
+/*-----------------------------------------------------------------------------
+ * Address translation macros declaration
+ *---------------------------------------------------------------------------*/
+
+/* 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. */
+
+/* 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. */
+
+
+/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8800)
++#if defined(__STN_8800)
+
+/* SDRAM bank 0 */
+#define SDRAM_BANK_0_BASE_ADDR 0x00000000
+#endif /* defined(__STN_8800) */
+
+/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8810)
++#if defined(__STN_8810)
+
+/* SDRAM bank 0 */
+#define SDRAM_BANK_0_BASE_ADDR 0x00000000
+#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 */
+//#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 */
+#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 */
+#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 */
+#endif /* defined(__EMUL) */
+
+/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8815)
++#if defined(__STN_8815)
+
+/* SDRAM bank 0 */
+#define SDRAM_BANK_0_BASE_ADDR 0x00000000
+#endif /* defined(__STN_8815) */
+
+/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8820)
++#if defined(__STN_8820)
+
+/* SDRAM bank 0 */
+#define SDRAM_BANK_0_BASE_ADDR 0x00000000
+#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. */
+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 */
+
+#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 */
+ 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 */
+
+#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 */
+} 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 */
+} 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 */
+} 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 */
+} 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 */
+} 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 */
+} 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 */
+}
+#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 */
+
+#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 */
+ #define HTI_PROTOCOL_STT
+
+#endif //_STT_PROTOCOL_H
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c 2008-07-17 16:43:00.000000000 +0530
-@@ -0,0 +1,557 @@
-+/*---------------------------------------------------------------------------*/
-+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
-+/* information, STMicroelectronics reserves the right to license this */
-+/* software concurrently under separate license conditions. */
-+/* */
-+/* This program is free software; you can redistribute it and/or modify it */
-+/* under the terms of the GNU Lesser General Public License as published */
-+/* by the Free Software Foundation; either version 2.1 of the License, */
-+/* or (at your option)any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, but */
-+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-+/* the GNU Lesser General Public License for more details. */
-+/* */
-+/* You should have received a copy of the GNU Lesser General Public License */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+/*---------------------------------------------------------------------------*/
-+
-+/*--------------------------------------------------------------------------*
-+ * Includes *
-+ *--------------------------------------------------------------------------*/
-+#include "saa_hwp.h"
-+#include "saap.h"
-+#include "hti.h"
-+#include "hti_protocol.h"
-+
-+
-+/*--------------------------------------------------------------------------*
-+ * Global variables *
-+ *--------------------------------------------------------------------------*/
-+t_saa_system saa_system;
-+t_bool saa_hcl_hti_trace = FALSE;
-+
-+
-+/*--------------------------------------------------------------------------*
-+ * Private data *
-+ *--------------------------------------------------------------------------*/
-+
-+/*--------------------------------------------------------------------------*
-+ * Public functions *
-+ *--------------------------------------------------------------------------*/
-+
-+/****************************************************************************/
-+/* NAME: SAA_InitSharedMailboxes */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Set the address of the shared uplink & downlink mailboxes. */
-+/* Called once when the first interrupt is received. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: - */
-+/* OUT: - */
-+/* RETURN: */
-+/* None */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC void SAA_InitSharedMailboxes(void) {
-+
-+ volatile t_uint16* ptr;
-+ t_uint32 offset;
-+ t_uint32 host_address = (t_uint32)&saa_system.pSAA_HW->host_reg;
-+ t_uint32 ram_address = (t_uint32)saa_system.pSAA_HW->ram;
-+
-+ // build the uplink shared mailbox address
-+ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_1);
-+ offset = (t_uint32)(*ptr) & 0xFF;
-+ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_2);
-+ offset <<= 8;
-+ offset |= (t_uint32)(*ptr) & 0xFF;
-+ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_3);
-+ offset <<= 8;
-+ offset |= (t_uint32)(*ptr) & 0xFF;
-+ offset <<= 1;
-+ saa_system.mailbox_ul.pMsg = (t_saa_message*)(ram_address + offset);
-+
-+ // build the downlink shared mailbox address
-+ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_1);
-+ offset = (t_uint32)(*ptr) & 0xFF;
-+ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_2);
-+ offset <<= 8;
-+ offset |= (t_uint32)(*ptr) & 0xFF;
-+ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_3);
-+ offset <<= 8;
-+ offset |= (t_uint32)(*ptr) & 0xFF;
-+ offset <<= 1;
-+ saa_system.mailbox_dl.pMsg = (t_saa_message*)(ram_address + offset);
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_SendCommand */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Send a command to the SAA/MMDSP. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: pCmd: pointer to the command description */
-+/* OUT: - */
-+/* RETURN: */
-+/* command number>0 if successful, 0 otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd) {
-+
-+ t_saa_message new_message;
-+ #ifdef SAA_USE_DOUBLE_IT
-+ t_saa_message message;
-+ int nb_msg_sent = 0;
-+ #endif
-+ int i;
-+
-+ new_message.command_number = (t_uint16)(saa_system.command_number + 1);
-+ new_message.command_id = pCmd->command_id;
-+ new_message.server_id = pCmd->server_id;
-+
-+ for (i=0; i<SAA_MSG_NB_PARAM; i++) {
-+ new_message.params[i] = pCmd->params[i];
-+ }
-+
-+ if (++saa_system.command_number == 0xFFFF)
-+ saa_system.command_number = 0; // avoid 16-bit roll-over of next command number (answer/alert mismatch)
-+
-+ #ifndef SAA_USE_DOUBLE_IT
-+ if (SAA_PutMessage(&new_message))
-+ {
-+ // send the write finished interrupt to SAA/MMDSP
-+ saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
-+
-+ return new_message.command_number;
-+ }
-+ #else
-+ SAA_DisableIRQSrc(ESAA_SRC_IRQ_1);
-+ // check if ARM is waiting for a read finished interrupt
-+ if(saa_system.rf_it_received){
-+ // copy all messages from ARM downlink local FIFO to downlink shared mailbox
-+ while ((nb_msg_sent < SAA_MBX_DOWN_SIZE)&&(SAA_PopFromLocalFifoDL(&message))){
-+ (void)SAA_PutMessage(&message);
-+ nb_msg_sent ++;
-+ }
-+
-+ if (SAA_PutMessage(&new_message)){
-+ // a read finished interrupt will be received
-+ saa_system.rf_it_received = FALSE;
-+
-+ // send the write finished interrupt to SAA/MMDSP
-+ saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
-+ SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
-+ return new_message.command_number;
-+ }
-+
-+ if(nb_msg_sent != 0){
-+ // a read finished interrupt will be received
-+ saa_system.rf_it_received = FALSE;
-+
-+ // send the write finished interrupt to SAA/MMDSP
-+ saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
-+ }
-+ }
-+
-+ // write new message to ARM downlink local FIFO
-+ if (SAA_PushToLocalFifoDL(&new_message)){
-+ SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
-+ return new_message.command_number;
-+ }
-+ SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
-+ #endif
-+
-+ return 0;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_PutMessage */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Put a message in the shared downlink mailbox. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: pMsg: pointer to the message description */
-+/* OUT: - */
-+/* RETURN: */
-+/* TRUE if successful, FALSE otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PutMessage(t_saa_message* pMsg) {
-+
-+ t_saa_message* pNewMsg;
-+ int i;
-+ #ifndef SAA_USE_DOUBLE_IT
-+ volatile t_uint32 *host_address = (t_uint32 *)&saa_system.pSAA_HW->host_reg;
-+ #endif
-+
-+ if (saa_system.mailbox_dl.pMsg == NULL)
-+ return FALSE;
-+
-+ pNewMsg = saa_system.mailbox_dl.pMsg + saa_system.mailbox_dl.index;
-+
-+ if ((pNewMsg->semaphore & 0x00FF) == 0) {
-+ pNewMsg->command_number = pMsg->command_number;
-+ pNewMsg->command_id = pMsg->command_id;
-+ pNewMsg->server_id = pMsg->server_id;
-+
-+ for (i=0; i<SAA_MSG_NB_PARAM; i++) {
-+ pNewMsg->params[i] = pMsg->params[i];
-+ }
-+
-+ if (++saa_system.mailbox_dl.index == SAA_MBX_DOWN_SIZE)
-+ saa_system.mailbox_dl.index = 0;
-+
-+ #ifndef SAA_USE_DOUBLE_IT
-+ while (host_address[HOST_HA_CMD1_SEM] != 0) {}
-+ host_address[HOST_HA_CMD1_SEM] = 1;
-+ #endif
-+
-+ pNewMsg->semaphore |= 0x0001;
-+
-+ if (saa_hcl_hti_trace)
-+ SAA_HtiTraceMsg(ESAA_DOWN_MSG, pMsg);
-+
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_GetMessage */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Get a message from the shared uplink mailbox. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: - */
-+/* OUT: pMsg: pointer to the message description */
-+/* RETURN: */
-+/* TRUE if successful, FALSE otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_GetMessage(t_saa_message* pMsg) {
-+
-+ t_saa_message* pNextMsg;
-+ int i;
-+
-+ if (saa_system.mailbox_ul.pMsg == NULL)
-+ return FALSE;
-+
-+ pNextMsg = saa_system.mailbox_ul.pMsg + saa_system.mailbox_ul.index;
-+
-+ if ((pNextMsg->semaphore & 0x00FF) == 0)
-+ return FALSE;
-+
-+ if (++saa_system.mailbox_ul.index == SAA_MBX_UP_SIZE)
-+ saa_system.mailbox_ul.index = 0;
-+
-+ pMsg->command_number = pNextMsg->command_number;
-+ pMsg->command_id = pNextMsg->command_id;
-+ pMsg->semaphore = pNextMsg->semaphore;
-+ pMsg->server_id = pNextMsg->server_id;
-+
-+ for (i=0; i<SAA_MSG_NB_PARAM; i++) {
-+ pMsg->params[i] = pNextMsg->params[i];
-+ }
-+
-+ pNextMsg->semaphore &= 0xFF00;
-+
-+ return TRUE;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_PushToLocalFifoUL */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Push a message to the ARM uplink local FIFO. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: pMsg: pointer to the message description */
-+/* OUT: - */
-+/* RETURN: */
-+/* TRUE if successful, FALSE otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PushToLocalFifoUL(t_saa_message* pMsg) {
-+
-+ t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
-+
-+ // check if FIFO is not full
-+ if (pFifoUL->unread_msg_counter < SAA_FIFO_UL_SIZE) {
-+ pFifoUL->message[pFifoUL->wr_position] = *pMsg;
-+
-+ pFifoUL->unread_msg_counter++;
-+
-+ if (++pFifoUL->wr_position == SAA_FIFO_UL_SIZE)
-+ pFifoUL->wr_position = 0;
-+
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_PopFromLocalFifoUL */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Pop a message from the ARM uplink local FIFO. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: - */
-+/* OUT: pMsg: pointer to the message description */
-+/* RETURN: */
-+/* TRUE if successful, FALSE otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PopFromLocalFifoUL(t_saa_message* pMsg) {
-+
-+ t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
-+
-+ // check if FIFO is not empty
-+ if (pFifoUL->unread_msg_counter) {
-+ *pMsg = pFifoUL->message[pFifoUL->rd_position];
-+
-+ pFifoUL->unread_msg_counter--;
-+
-+ if (++pFifoUL->rd_position == SAA_FIFO_UL_SIZE)
-+ pFifoUL->rd_position = 0;
-+
-+ if (saa_hcl_hti_trace)
-+ SAA_HtiTraceMsg(ESAA_UP_MSG, pMsg);
-+
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+#ifdef SAA_USE_DOUBLE_IT
-+/****************************************************************************/
-+/* NAME: SAA_PushToLocalFifoDL */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Push a message to the ARM local downlink FIFO. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: pMsg: pointer to the message description */
-+/* OUT: - */
-+/* RETURN: */
-+/* TRUE if successful, FALSE otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PushToLocalFifoDL(t_saa_message* pMsg) {
-+
-+ t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
-+
-+ // check if FIFO is not full
-+ if (pFifoDL->unsent_msg_counter < SAA_FIFO_DL_SIZE) {
-+ pFifoDL->message[pFifoDL->wr_position] = *pMsg;
-+
-+ pFifoDL->unsent_msg_counter++;
-+
-+ if (++pFifoDL->wr_position == SAA_FIFO_DL_SIZE)
-+ pFifoDL->wr_position = 0;
-+
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_PopFromLocalFifoDL */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Pop a message from the ARM local downlink FIFO. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: - */
-+/* OUT: pMsg: pointer to the message description */
-+/* RETURN: */
-+/* TRUE if successful, FALSE otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PopFromLocalFifoDL(t_saa_message* pMsg) {
-+
-+ t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
-+
-+ // check if FIFO is not empty
-+ if (pFifoDL->unsent_msg_counter) {
-+ *pMsg = pFifoDL->message[pFifoDL->rd_position];
-+
-+ pFifoDL->unsent_msg_counter--;
-+
-+ if (++pFifoDL->rd_position == SAA_FIFO_DL_SIZE)
-+ pFifoDL->rd_position = 0;
-+
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+#endif
-+
-+/****************************************************************************/
-+/* NAME: SAA_NewComponent */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Find a new entry in the component table. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: - */
-+/* OUT: - */
-+/* RETURN: */
-+/* pointer to new entry if successful, NULL otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_saa_component_entry* SAA_NewComponent(void) {
-+
-+ t_saa_component_entry* pComponent = saa_system.component;
-+ int i;
-+
-+ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+ {
-+ if (pComponent->block_id == 0)
-+ return pComponent;
-+ }
-+
-+ return NULL;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_FindComponent */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Find a given component. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: block_id: identifier of the block */
-+/* component_id: identifier of the component */
-+/* OUT: - */
-+/* RETURN: */
-+/* pointer to entry if successful, NULL otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_saa_component_entry* SAA_FindComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
-+
-+ t_saa_component_entry* pComponent = saa_system.component;
-+ int i;
-+
-+ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+ {
-+ if (pComponent->block_id == block_id && pComponent->component_id == component_id)
-+ {
-+ return pComponent;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_FreeComponent */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Free an existing component. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: block_id: identifier of the block */
-+/* component_id: identifier of the component */
-+/* OUT: - */
-+/* RETURN: */
-+/* pointer to old entry if successful, NULL otherwise */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_saa_component_entry* SAA_FreeComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
-+
-+ t_saa_component_entry* pComponent = saa_system.component;
-+ int i;
-+
-+ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+ {
-+ if (pComponent->block_id == block_id && pComponent->component_id == component_id)
-+ {
-+ pComponent->block_id = 0;
-+ return pComponent;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_FreeAllComponents */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Free all components of an existing block. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: block_id: identifier of the block */
-+/* OUT: - */
-+/* RETURN: */
-+/* Number of components freed */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+PUBLIC t_uint16 SAA_FreeAllComponents(t_saa_block_id block_id) {
-+
-+ t_saa_component_entry* pComponent = saa_system.component;
-+ t_uint16 nb_components = 0;
-+ int i;
-+
-+ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+ {
-+ if (pComponent->block_id == block_id)
-+ {
-+ pComponent->block_id = 0;
-+ nb_components++;
-+ }
-+ }
-+
-+ return nb_components;
-+}
-+
-+/****************************************************************************/
-+/* NAME: SAA_HtiTraceMsg */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Sends a message to the HTI debug port. */
-+/* */
-+/* PARAMETERS: */
-+/* IN: msg_dir: direction of message (uplink/downlink) */
-+/* pMsg: pointer to the message to be sent */
-+/* OUT: - */
-+/* RETURN: void */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA */
-+/****************************************************************************/
-+
-+
-+PUBLIC void SAA_HtiTraceMsg(t_saa_msg_dir msg_dir, t_saa_message* pMsg)
-+{
-+ t_uint16* pDynParams;
-+
-+ HTI_CMD_SAA_HCL(SAA_HCL_HTI_CHANNEL);
-+
-+ if ((pMsg->command_id==HA_CMD_CONFIG_COMPONENT) && (msg_dir==ESAA_DOWN_MSG)){
-+ HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir + 0XF0); // specify not standart message
-+ HtiSendn_32(SAA_HCL_HTI_CHANNEL,(const HTI_U32 *)pMsg, 3); //semaphore command_number server_id command_id params[0] params[1]
-+ pDynParams = (t_uint16*)(((t_uint32)pMsg->params[3])<<16 | pMsg->params[2]); // param address
-+ HtiSend_16(SAA_HCL_HTI_CHANNEL, pMsg->params[4]); // nb param
-+ HtiSendn_16(SAA_HCL_HTI_CHANNEL, pDynParams, pMsg->params[4]);
-+ }
-+ else{
-+ HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir);
-+ HtiSendn_32(SAA_HCL_HTI_CHANNEL, (const HTI_U32 *)pMsg, sizeof(t_saa_message)/ sizeof(int));
-+
-+ }
-+ HTI_CMD_END_OF_CHANNEL(SAA_HCL_HTI_CHANNEL);
-+
-+
-+}
-+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c 2008-07-17 16:42:58.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c
@@ -0,0 +1,2538 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+
+ 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 */
+#endif // __cplusplus
+
+#endif // __INC_SAA_H
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h 2008-07-17 16:43:00.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c
+@@ -0,0 +1,557 @@
++/*---------------------------------------------------------------------------*/
++/* © copyright STMicroelectronics, 2007. All rights reserved. For */
++/* information, STMicroelectronics reserves the right to license this */
++/* software concurrently under separate license conditions. */
++/* */
++/* This program is free software; you can redistribute it and/or modify it */
++/* under the terms of the GNU Lesser General Public License as published */
++/* by the Free Software Foundation; either version 2.1 of the License, */
++/* or (at your option)any later version. */
++/* */
++/* This program is distributed in the hope that it will be useful, but */
++/* WITHOUT ANY WARRANTY; without even the implied warranty of */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
++/* the GNU Lesser General Public License for more details. */
++/* */
++/* You should have received a copy of the GNU Lesser General Public License */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
++/*---------------------------------------------------------------------------*/
++
++/*--------------------------------------------------------------------------*
++ * Includes *
++ *--------------------------------------------------------------------------*/
++#include "saa_hwp.h"
++#include "saap.h"
++#include "hti.h"
++#include "hti_protocol.h"
++
++
++/*--------------------------------------------------------------------------*
++ * Global variables *
++ *--------------------------------------------------------------------------*/
++t_saa_system saa_system;
++t_bool saa_hcl_hti_trace = FALSE;
++
++
++/*--------------------------------------------------------------------------*
++ * Private data *
++ *--------------------------------------------------------------------------*/
++
++/*--------------------------------------------------------------------------*
++ * Public functions *
++ *--------------------------------------------------------------------------*/
++
++/****************************************************************************/
++/* NAME: SAA_InitSharedMailboxes */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Set the address of the shared uplink & downlink mailboxes. */
++/* Called once when the first interrupt is received. */
++/* */
++/* PARAMETERS: */
++/* IN: - */
++/* OUT: - */
++/* RETURN: */
++/* None */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC void SAA_InitSharedMailboxes(void) {
++
++ volatile t_uint16* ptr;
++ t_uint32 offset;
++ t_uint32 host_address = (t_uint32)&saa_system.pSAA_HW->host_reg;
++ t_uint32 ram_address = (t_uint32)saa_system.pSAA_HW->ram;
++
++ // build the uplink shared mailbox address
++ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_1);
++ offset = (t_uint32)(*ptr) & 0xFF;
++ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_2);
++ offset <<= 8;
++ offset |= (t_uint32)(*ptr) & 0xFF;
++ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_3);
++ offset <<= 8;
++ offset |= (t_uint32)(*ptr) & 0xFF;
++ offset <<= 1;
++ saa_system.mailbox_ul.pMsg = (t_saa_message*)(ram_address + offset);
++
++ // build the downlink shared mailbox address
++ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_1);
++ offset = (t_uint32)(*ptr) & 0xFF;
++ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_2);
++ offset <<= 8;
++ offset |= (t_uint32)(*ptr) & 0xFF;
++ ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_3);
++ offset <<= 8;
++ offset |= (t_uint32)(*ptr) & 0xFF;
++ offset <<= 1;
++ saa_system.mailbox_dl.pMsg = (t_saa_message*)(ram_address + offset);
++}
++
++/****************************************************************************/
++/* NAME: SAA_SendCommand */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Send a command to the SAA/MMDSP. */
++/* */
++/* PARAMETERS: */
++/* IN: pCmd: pointer to the command description */
++/* OUT: - */
++/* RETURN: */
++/* command number>0 if successful, 0 otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd) {
++
++ t_saa_message new_message;
++ #ifdef SAA_USE_DOUBLE_IT
++ t_saa_message message;
++ int nb_msg_sent = 0;
++ #endif
++ int i;
++
++ new_message.command_number = (t_uint16)(saa_system.command_number + 1);
++ new_message.command_id = pCmd->command_id;
++ new_message.server_id = pCmd->server_id;
++
++ for (i=0; i<SAA_MSG_NB_PARAM; i++) {
++ new_message.params[i] = pCmd->params[i];
++ }
++
++ if (++saa_system.command_number == 0xFFFF)
++ saa_system.command_number = 0; // avoid 16-bit roll-over of next command number (answer/alert mismatch)
++
++ #ifndef SAA_USE_DOUBLE_IT
++ if (SAA_PutMessage(&new_message))
++ {
++ // send the write finished interrupt to SAA/MMDSP
++ saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
++
++ return new_message.command_number;
++ }
++ #else
++ SAA_DisableIRQSrc(ESAA_SRC_IRQ_1);
++ // check if ARM is waiting for a read finished interrupt
++ if(saa_system.rf_it_received){
++ // copy all messages from ARM downlink local FIFO to downlink shared mailbox
++ while ((nb_msg_sent < SAA_MBX_DOWN_SIZE)&&(SAA_PopFromLocalFifoDL(&message))){
++ (void)SAA_PutMessage(&message);
++ nb_msg_sent ++;
++ }
++
++ if (SAA_PutMessage(&new_message)){
++ // a read finished interrupt will be received
++ saa_system.rf_it_received = FALSE;
++
++ // send the write finished interrupt to SAA/MMDSP
++ saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
++ SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
++ return new_message.command_number;
++ }
++
++ if(nb_msg_sent != 0){
++ // a read finished interrupt will be received
++ saa_system.rf_it_received = FALSE;
++
++ // send the write finished interrupt to SAA/MMDSP
++ saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
++ }
++ }
++
++ // write new message to ARM downlink local FIFO
++ if (SAA_PushToLocalFifoDL(&new_message)){
++ SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
++ return new_message.command_number;
++ }
++ SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
++ #endif
++
++ return 0;
++}
++
++/****************************************************************************/
++/* NAME: SAA_PutMessage */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Put a message in the shared downlink mailbox. */
++/* */
++/* PARAMETERS: */
++/* IN: pMsg: pointer to the message description */
++/* OUT: - */
++/* RETURN: */
++/* TRUE if successful, FALSE otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_bool SAA_PutMessage(t_saa_message* pMsg) {
++
++ t_saa_message* pNewMsg;
++ int i;
++ #ifndef SAA_USE_DOUBLE_IT
++ volatile t_uint32 *host_address = (t_uint32 *)&saa_system.pSAA_HW->host_reg;
++ #endif
++
++ if (saa_system.mailbox_dl.pMsg == NULL)
++ return FALSE;
++
++ pNewMsg = saa_system.mailbox_dl.pMsg + saa_system.mailbox_dl.index;
++
++ if ((pNewMsg->semaphore & 0x00FF) == 0) {
++ pNewMsg->command_number = pMsg->command_number;
++ pNewMsg->command_id = pMsg->command_id;
++ pNewMsg->server_id = pMsg->server_id;
++
++ for (i=0; i<SAA_MSG_NB_PARAM; i++) {
++ pNewMsg->params[i] = pMsg->params[i];
++ }
++
++ if (++saa_system.mailbox_dl.index == SAA_MBX_DOWN_SIZE)
++ saa_system.mailbox_dl.index = 0;
++
++ #ifndef SAA_USE_DOUBLE_IT
++ while (host_address[HOST_HA_CMD1_SEM] != 0) {}
++ host_address[HOST_HA_CMD1_SEM] = 1;
++ #endif
++
++ pNewMsg->semaphore |= 0x0001;
++
++ if (saa_hcl_hti_trace)
++ SAA_HtiTraceMsg(ESAA_DOWN_MSG, pMsg);
++
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++/****************************************************************************/
++/* NAME: SAA_GetMessage */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Get a message from the shared uplink mailbox. */
++/* */
++/* PARAMETERS: */
++/* IN: - */
++/* OUT: pMsg: pointer to the message description */
++/* RETURN: */
++/* TRUE if successful, FALSE otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_bool SAA_GetMessage(t_saa_message* pMsg) {
++
++ t_saa_message* pNextMsg;
++ int i;
++
++ if (saa_system.mailbox_ul.pMsg == NULL)
++ return FALSE;
++
++ pNextMsg = saa_system.mailbox_ul.pMsg + saa_system.mailbox_ul.index;
++
++ if ((pNextMsg->semaphore & 0x00FF) == 0)
++ return FALSE;
++
++ if (++saa_system.mailbox_ul.index == SAA_MBX_UP_SIZE)
++ saa_system.mailbox_ul.index = 0;
++
++ pMsg->command_number = pNextMsg->command_number;
++ pMsg->command_id = pNextMsg->command_id;
++ pMsg->semaphore = pNextMsg->semaphore;
++ pMsg->server_id = pNextMsg->server_id;
++
++ for (i=0; i<SAA_MSG_NB_PARAM; i++) {
++ pMsg->params[i] = pNextMsg->params[i];
++ }
++
++ pNextMsg->semaphore &= 0xFF00;
++
++ return TRUE;
++}
++
++/****************************************************************************/
++/* NAME: SAA_PushToLocalFifoUL */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Push a message to the ARM uplink local FIFO. */
++/* */
++/* PARAMETERS: */
++/* IN: pMsg: pointer to the message description */
++/* OUT: - */
++/* RETURN: */
++/* TRUE if successful, FALSE otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_bool SAA_PushToLocalFifoUL(t_saa_message* pMsg) {
++
++ t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
++
++ // check if FIFO is not full
++ if (pFifoUL->unread_msg_counter < SAA_FIFO_UL_SIZE) {
++ pFifoUL->message[pFifoUL->wr_position] = *pMsg;
++
++ pFifoUL->unread_msg_counter++;
++
++ if (++pFifoUL->wr_position == SAA_FIFO_UL_SIZE)
++ pFifoUL->wr_position = 0;
++
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++/****************************************************************************/
++/* NAME: SAA_PopFromLocalFifoUL */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Pop a message from the ARM uplink local FIFO. */
++/* */
++/* PARAMETERS: */
++/* IN: - */
++/* OUT: pMsg: pointer to the message description */
++/* RETURN: */
++/* TRUE if successful, FALSE otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_bool SAA_PopFromLocalFifoUL(t_saa_message* pMsg) {
++
++ t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
++
++ // check if FIFO is not empty
++ if (pFifoUL->unread_msg_counter) {
++ *pMsg = pFifoUL->message[pFifoUL->rd_position];
++
++ pFifoUL->unread_msg_counter--;
++
++ if (++pFifoUL->rd_position == SAA_FIFO_UL_SIZE)
++ pFifoUL->rd_position = 0;
++
++ if (saa_hcl_hti_trace)
++ SAA_HtiTraceMsg(ESAA_UP_MSG, pMsg);
++
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++#ifdef SAA_USE_DOUBLE_IT
++/****************************************************************************/
++/* NAME: SAA_PushToLocalFifoDL */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Push a message to the ARM local downlink FIFO. */
++/* */
++/* PARAMETERS: */
++/* IN: pMsg: pointer to the message description */
++/* OUT: - */
++/* RETURN: */
++/* TRUE if successful, FALSE otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_bool SAA_PushToLocalFifoDL(t_saa_message* pMsg) {
++
++ t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
++
++ // check if FIFO is not full
++ if (pFifoDL->unsent_msg_counter < SAA_FIFO_DL_SIZE) {
++ pFifoDL->message[pFifoDL->wr_position] = *pMsg;
++
++ pFifoDL->unsent_msg_counter++;
++
++ if (++pFifoDL->wr_position == SAA_FIFO_DL_SIZE)
++ pFifoDL->wr_position = 0;
++
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++/****************************************************************************/
++/* NAME: SAA_PopFromLocalFifoDL */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Pop a message from the ARM local downlink FIFO. */
++/* */
++/* PARAMETERS: */
++/* IN: - */
++/* OUT: pMsg: pointer to the message description */
++/* RETURN: */
++/* TRUE if successful, FALSE otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_bool SAA_PopFromLocalFifoDL(t_saa_message* pMsg) {
++
++ t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
++
++ // check if FIFO is not empty
++ if (pFifoDL->unsent_msg_counter) {
++ *pMsg = pFifoDL->message[pFifoDL->rd_position];
++
++ pFifoDL->unsent_msg_counter--;
++
++ if (++pFifoDL->rd_position == SAA_FIFO_DL_SIZE)
++ pFifoDL->rd_position = 0;
++
++ return TRUE;
++ }
++
++ return FALSE;
++}
++#endif
++
++/****************************************************************************/
++/* NAME: SAA_NewComponent */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Find a new entry in the component table. */
++/* */
++/* PARAMETERS: */
++/* IN: - */
++/* OUT: - */
++/* RETURN: */
++/* pointer to new entry if successful, NULL otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_saa_component_entry* SAA_NewComponent(void) {
++
++ t_saa_component_entry* pComponent = saa_system.component;
++ int i;
++
++ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++ {
++ if (pComponent->block_id == 0)
++ return pComponent;
++ }
++
++ return NULL;
++}
++
++/****************************************************************************/
++/* NAME: SAA_FindComponent */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Find a given component. */
++/* */
++/* PARAMETERS: */
++/* IN: block_id: identifier of the block */
++/* component_id: identifier of the component */
++/* OUT: - */
++/* RETURN: */
++/* pointer to entry if successful, NULL otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_saa_component_entry* SAA_FindComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
++
++ t_saa_component_entry* pComponent = saa_system.component;
++ int i;
++
++ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++ {
++ if (pComponent->block_id == block_id && pComponent->component_id == component_id)
++ {
++ return pComponent;
++ }
++ }
++
++ return NULL;
++}
++
++/****************************************************************************/
++/* NAME: SAA_FreeComponent */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Free an existing component. */
++/* */
++/* PARAMETERS: */
++/* IN: block_id: identifier of the block */
++/* component_id: identifier of the component */
++/* OUT: - */
++/* RETURN: */
++/* pointer to old entry if successful, NULL otherwise */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_saa_component_entry* SAA_FreeComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
++
++ t_saa_component_entry* pComponent = saa_system.component;
++ int i;
++
++ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++ {
++ if (pComponent->block_id == block_id && pComponent->component_id == component_id)
++ {
++ pComponent->block_id = 0;
++ return pComponent;
++ }
++ }
++
++ return NULL;
++}
++
++/****************************************************************************/
++/* NAME: SAA_FreeAllComponents */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Free all components of an existing block. */
++/* */
++/* PARAMETERS: */
++/* IN: block_id: identifier of the block */
++/* OUT: - */
++/* RETURN: */
++/* Number of components freed */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++PUBLIC t_uint16 SAA_FreeAllComponents(t_saa_block_id block_id) {
++
++ t_saa_component_entry* pComponent = saa_system.component;
++ t_uint16 nb_components = 0;
++ int i;
++
++ for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++ {
++ if (pComponent->block_id == block_id)
++ {
++ pComponent->block_id = 0;
++ nb_components++;
++ }
++ }
++
++ return nb_components;
++}
++
++/****************************************************************************/
++/* NAME: SAA_HtiTraceMsg */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Sends a message to the HTI debug port. */
++/* */
++/* PARAMETERS: */
++/* IN: msg_dir: direction of message (uplink/downlink) */
++/* pMsg: pointer to the message to be sent */
++/* OUT: - */
++/* RETURN: void */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA */
++/****************************************************************************/
++
++
++PUBLIC void SAA_HtiTraceMsg(t_saa_msg_dir msg_dir, t_saa_message* pMsg)
++{
++ t_uint16* pDynParams;
++
++ HTI_CMD_SAA_HCL(SAA_HCL_HTI_CHANNEL);
++
++ if ((pMsg->command_id==HA_CMD_CONFIG_COMPONENT) && (msg_dir==ESAA_DOWN_MSG)){
++ HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir + 0XF0); // specify not standart message
++ HtiSendn_32(SAA_HCL_HTI_CHANNEL,(const HTI_U32 *)pMsg, 3); //semaphore command_number server_id command_id params[0] params[1]
++ pDynParams = (t_uint16*)(((t_uint32)pMsg->params[3])<<16 | pMsg->params[2]); // param address
++ HtiSend_16(SAA_HCL_HTI_CHANNEL, pMsg->params[4]); // nb param
++ HtiSendn_16(SAA_HCL_HTI_CHANNEL, pDynParams, pMsg->params[4]);
++ }
++ else{
++ HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir);
++ HtiSendn_32(SAA_HCL_HTI_CHANNEL, (const HTI_U32 *)pMsg, sizeof(t_saa_message)/ sizeof(int));
++
++ }
++ HTI_CMD_END_OF_CHANNEL(SAA_HCL_HTI_CHANNEL);
++
++
++}
++
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h
@@ -0,0 +1,275 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+#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 */
+
+ 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 */
+#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 */
+}
+
+// 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 */
+
+#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 */
+
+#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 */
+#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 */
+
+ 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 */
+
+#endif /* __INC_SVA_IN_H */
+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h 2008-07-17 16:45:19.000000000 +0530
-@@ -0,0 +1,188 @@
-+/*---------------------------------------------------------------------------*/
-+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
-+/* information, STMicroelectronics reserves the right to license this */
-+/* software concurrently under separate license conditions. */
-+/* */
-+/* This program is free software; you can redistribute it and/or modify it */
-+/* under the terms of the GNU Lesser General Public License as published */
-+/* by the Free Software Foundation; either version 2.1 of the License, */
-+/* or (at your option)any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, but */
-+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-+/* the GNU Lesser General Public License for more details. */
-+/* */
-+/* You should have received a copy of the GNU Lesser General Public License */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVAP_H
-+#define __INC_SVAP_H
-+
-+#include "hcl_defs.h"
-+
-+/******************************************************************************/
-+/* Constants definitions */
-+/******************************************************************************/
-+/*
-+ * Define various conditonnal compilation flags in order to include or not any SW workarounds
-+ */
-+/*#define WORK_AROUND_AHB*/
-+
-+/*
-+ * Define the maximum number of error defined per module
-+ */
-+#define SVA_MODULE_ERROR_RANGE 0x20
-+
-+/*
-+ * Define an Id related to each module of the SVA HCL
-+ * The Id = 1 is reserved for SVA HCL itself
-+ */
-+typedef enum {
-+ SVA_EM_ID = 2, /* Events Mgt */
-+ SVA_MM_ID, /* Memory Mgt */
-+ SVA_BM_ID, /* Buffers Mgt */
-+ SVA_BLM_ID, /* Buffers ListMgt */
-+ SVA_TM_ID, /* Tasks Mgt */
-+ SVA_FM_ID, /* Firmware Mgt */
-+ SVA_TI_ID, /* Time Mgt */
-+ SVA_VP_ID, /* Video Pipeline */
-+ SVA_FF_ID, /* FIFO macros */
-+ SVA_IN_ID, /* Internal Needs Mgt */
-+ SVA_SV_ID, /* Common Service */
-+ SVA_DP_ID, /* Display Service */
-+ SVA_DC_ID, /* Decode Service */
-+ SVA_EC_ID, /* Encode Service */
-+ SVA_GB_ID, /* Grab Service */
-+ SVA_DC_ERC_ID, /* Decode Error Concealment */
-+ SVA_DC_MP4_ID, /* Decode MPEG4 Algo */
-+ SVA_DC_H263_ID, /* Decode H263 Algo */
-+ SVA_DC_H264_ID, /* Decode H263 Algo */
-+ SVA_EC_BRC_ID, /* Encode Bit Rate Control */
-+ SVA_EC_MP4_ID, /* Encode MPEG4 Algo */
-+ SVA_EC_H263_ID, /* Encode H263 Algo */
-+ SVA_EC_H264_ID, /* Encode H264 Algo */
-+ SVA_EC_STAB_ID, /* Encode Stabilization */
-+ SVA_SEC_JPEG_ID, /* Still Encode JPEG ALgo */
-+ SVA_SEC_ID, /* still Encode service */
-+ SVA_TV_ID /* TVO Service */
-+} sva_module_id;
-+
-+/* ************************** CONFIGURATION PART ************************** */
-+typedef struct {
-+ t_uint32 cfg_psa; /* Subtask parameter Start Address register */
-+ t_uint32 cfg_pea; /* Subtask parameter Stop Address register */
-+ t_uint32 cfg_ice; /* Idle Cycle Enable register */
-+ t_uint32 cfg_csc; /* CCP synchronization codes register */
-+ t_uint32 cfg_cgc; /* clock gating control register */
-+ t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
-+ t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
-+ t_uint32 cfg_irp_rw; /* status of the current rw operation */
-+ t_uint32 cfg_irp_error; /* error code */
-+ t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
-+ t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
-+ t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
-+ t_uint32 cfg_clk; /* Clock generation register */
-+ t_uint32 ckg_cken; /* added*/
-+ t_uint32 cfg_tim; /* Timer Initialization value register */
-+ t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */
-+ t_uint32 cfg_isr; /* Global Interrupt status register */
-+ t_uint32 cfg_imr; /* Global Interrupt mask register */
-+// t_uint32 wasDeepSleepEntered;
-+ t_uint32 temp_idn_frv;
-+ t_sva_fw_id fwId;
-+ t_uint32 sva_context_magic_number;
-+} t_sva_config_regs_mapping1;
-+
-+#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
-+
-+#define SVA_EM_LAST_ERROR (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EM_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_MM_LAST_ERROR (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_MM_FIRST_INFO (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BM_LAST_ERROR (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BM_FIRST_INFO (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BLM_LAST_ERROR (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BLM_FIRST_INFO (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TM_LAST_ERROR (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TM_FIRST_INFO (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FM_LAST_ERROR (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FM_FIRST_INFO (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TI_LAST_ERROR (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TI_FIRST_INFO (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FF_LAST_ERROR (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FF_FIRST_INFO (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_IN_LAST_ERROR (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_IN_FIRST_INFO (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SV_LAST_ERROR (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SV_FIRST_INFO (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DP_LAST_ERROR (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DP_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_LAST_ERROR (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_FIRST_INFO (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_LAST_ERROR (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_FIRST_INFO (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_GB_LAST_ERROR (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_GB_FIRST_INFO (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H263_LAST_ERROR (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H263_FIRST_INFO (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H264_LAST_ERROR (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H264_FIRST_INFO (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+
-+#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H263_LAST_ERROR (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H263_FIRST_INFO (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H264_LAST_ERROR (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H264_FIRST_INFO (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_STAB_LAST_ERROR (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_STAB_FIRST_INFO (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_JPEG_LAST_ERROR (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_JPEG_FIRST_INFO (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_LAST_ERROR (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_FIRST_INFO (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TV_LAST_ERROR (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TV_FIRST_ERROR (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+/******************************************************************************/
-+/* Types definitions */
-+/******************************************************************************/
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif /* __cplusplus */
-+
-+#endif /* __INC_SVAP_H */
-+/* End of file - hvP.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h 2008-07-17 16:45:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h
@@ -0,0 +1,337 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+
+#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 */
+
+
+/* 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 */
+
+#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 */
+#endif /* __INC_SVA_TIP_H */
+/* End of file - sva_timemgt.h */
+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c 2008-08-12 22:56:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h
+@@ -0,0 +1,188 @@
++/*---------------------------------------------------------------------------*/
++/* © copyright STMicroelectronics, 2007. All rights reserved. For */
++/* information, STMicroelectronics reserves the right to license this */
++/* software concurrently under separate license conditions. */
++/* */
++/* This program is free software; you can redistribute it and/or modify it */
++/* under the terms of the GNU Lesser General Public License as published */
++/* by the Free Software Foundation; either version 2.1 of the License, */
++/* or (at your option)any later version. */
++/* */
++/* This program is distributed in the hope that it will be useful, but */
++/* WITHOUT ANY WARRANTY; without even the implied warranty of */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
++/* the GNU Lesser General Public License for more details. */
++/* */
++/* You should have received a copy of the GNU Lesser General Public License */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVAP_H
++#define __INC_SVAP_H
++
++#include "hcl_defs.h"
++
++/******************************************************************************/
++/* Constants definitions */
++/******************************************************************************/
++/*
++ * Define various conditonnal compilation flags in order to include or not any SW workarounds
++ */
++/*#define WORK_AROUND_AHB*/
++
++/*
++ * Define the maximum number of error defined per module
++ */
++#define SVA_MODULE_ERROR_RANGE 0x20
++
++/*
++ * Define an Id related to each module of the SVA HCL
++ * The Id = 1 is reserved for SVA HCL itself
++ */
++typedef enum {
++ SVA_EM_ID = 2, /* Events Mgt */
++ SVA_MM_ID, /* Memory Mgt */
++ SVA_BM_ID, /* Buffers Mgt */
++ SVA_BLM_ID, /* Buffers ListMgt */
++ SVA_TM_ID, /* Tasks Mgt */
++ SVA_FM_ID, /* Firmware Mgt */
++ SVA_TI_ID, /* Time Mgt */
++ SVA_VP_ID, /* Video Pipeline */
++ SVA_FF_ID, /* FIFO macros */
++ SVA_IN_ID, /* Internal Needs Mgt */
++ SVA_SV_ID, /* Common Service */
++ SVA_DP_ID, /* Display Service */
++ SVA_DC_ID, /* Decode Service */
++ SVA_EC_ID, /* Encode Service */
++ SVA_GB_ID, /* Grab Service */
++ SVA_DC_ERC_ID, /* Decode Error Concealment */
++ SVA_DC_MP4_ID, /* Decode MPEG4 Algo */
++ SVA_DC_H263_ID, /* Decode H263 Algo */
++ SVA_DC_H264_ID, /* Decode H263 Algo */
++ SVA_EC_BRC_ID, /* Encode Bit Rate Control */
++ SVA_EC_MP4_ID, /* Encode MPEG4 Algo */
++ SVA_EC_H263_ID, /* Encode H263 Algo */
++ SVA_EC_H264_ID, /* Encode H264 Algo */
++ SVA_EC_STAB_ID, /* Encode Stabilization */
++ SVA_SEC_JPEG_ID, /* Still Encode JPEG ALgo */
++ SVA_SEC_ID, /* still Encode service */
++ SVA_TV_ID /* TVO Service */
++} sva_module_id;
++
++/* ************************** CONFIGURATION PART ************************** */
++typedef struct {
++ t_uint32 cfg_psa; /* Subtask parameter Start Address register */
++ t_uint32 cfg_pea; /* Subtask parameter Stop Address register */
++ t_uint32 cfg_ice; /* Idle Cycle Enable register */
++ t_uint32 cfg_csc; /* CCP synchronization codes register */
++ t_uint32 cfg_cgc; /* clock gating control register */
++ t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
++ t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
++ t_uint32 cfg_irp_rw; /* status of the current rw operation */
++ t_uint32 cfg_irp_error; /* error code */
++ t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
++ t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
++ t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
++ t_uint32 cfg_clk; /* Clock generation register */
++ t_uint32 ckg_cken; /* added*/
++ t_uint32 cfg_tim; /* Timer Initialization value register */
++ t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */
++ t_uint32 cfg_isr; /* Global Interrupt status register */
++ t_uint32 cfg_imr; /* Global Interrupt mask register */
++// t_uint32 wasDeepSleepEntered;
++ t_uint32 temp_idn_frv;
++ t_sva_fw_id fwId;
++ t_uint32 sva_context_magic_number;
++} t_sva_config_regs_mapping1;
++
++#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
++
++#define SVA_EM_LAST_ERROR (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EM_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_MM_LAST_ERROR (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_MM_FIRST_INFO (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BM_LAST_ERROR (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BM_FIRST_INFO (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BLM_LAST_ERROR (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BLM_FIRST_INFO (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TM_LAST_ERROR (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TM_FIRST_INFO (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FM_LAST_ERROR (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FM_FIRST_INFO (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TI_LAST_ERROR (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TI_FIRST_INFO (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FF_LAST_ERROR (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FF_FIRST_INFO (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_IN_LAST_ERROR (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_IN_FIRST_INFO (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SV_LAST_ERROR (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SV_FIRST_INFO (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DP_LAST_ERROR (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DP_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_LAST_ERROR (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_FIRST_INFO (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_LAST_ERROR (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_FIRST_INFO (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_GB_LAST_ERROR (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_GB_FIRST_INFO (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H263_LAST_ERROR (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H263_FIRST_INFO (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H264_LAST_ERROR (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H264_FIRST_INFO (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++
++#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H263_LAST_ERROR (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H263_FIRST_INFO (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H264_LAST_ERROR (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H264_FIRST_INFO (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_STAB_LAST_ERROR (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_STAB_FIRST_INFO (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_JPEG_LAST_ERROR (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_JPEG_FIRST_INFO (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_LAST_ERROR (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_FIRST_INFO (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TV_LAST_ERROR (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TV_FIRST_ERROR (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++/******************************************************************************/
++/* Types definitions */
++/******************************************************************************/
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif /* __cplusplus */
++
++#endif /* __INC_SVAP_H */
++/* End of file - hvP.h */
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c
@@ -0,0 +1,3030 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+}
+
+// End of file - sva_dc_h264.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c 2008-08-12 22:56:11.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h
+@@ -0,0 +1,110 @@
++/*---------------------------------------------------------------------------*/
++/* © copyright STMicroelectronics, 2007. All rights reserved. For */
++/* information, STMicroelectronics reserves the right to license this */
++/* software concurrently under separate license conditions. */
++/* */
++/* This program is free software; you can redistribute it and/or modify it */
++/* under the terms of the GNU Lesser General Public License as published */
++/* by the Free Software Foundation; either version 2.1 of the License, */
++/* or (at your option)any later version. */
++/* */
++/* This program is distributed in the hope that it will be useful, but */
++/* WITHOUT ANY WARRANTY; without even the implied warranty of */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
++/* the GNU Lesser General Public License for more details. */
++/* */
++/* You should have received a copy of the GNU Lesser General Public License */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVA_DC_H264_H
++#define __INC_SVA_DC_H264_H
++
++#include "hcl_defs.h"
++#include "sva_service.h"
++#include "sva_dc_h264_dpb.h"
++#include "sva_dc_h264_slicemap.h"
++
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#ifdef __DEBUG
++#define SVA_DC_H264_MAX_DBG_DEPTH 30
++#define SVA_DC_H264_MAX_DBG_SLICESPERFRAME 9
++#define SVA_DC_H264_MAX_DBG_EVENTS 12
++#endif
++
++/* macros */
++#define H264MIN(a,b) (((a)<(b))?a:b)
++#define H264MAX(a,b) (((a)>(b))?a:b)
++#define H264_MAX_UINT_16 65535
++#define H264_MAX_SINT_32 2147483647
++#define H264_MIN_SINT_32 -H264_MAX_SINT_32-1
++#define H264_MAX_UINT_32 4294967295
++
++/* extracted from each slice headers of the frame and required to program vdc_h264_slice */
++typedef t_sva_h264_dpb_params_slice t_sva_h264_params_slice;
++
++
++/* used as parameter for SetHeaderInfo */
++typedef struct
++{ /* from active PPS */
++ t_uint16 chromaQpIndex;
++ t_uint16 constrIntraPredFlag;
++ t_uint16 numRefIdxl0ActiveMinus1;
++}t_sva_h264_active_pps;
++
++
++/* extracted from active PPS and first slice Header, used to compute sliceMap */
++typedef t_sva_h264_slicemap t_sva_h264_slicemap_info;
++
++
++
++/* public fonctions */
++PUBLIC t_sva_error sva_DC_H264_Init( t_sva_service_instance_num , t_sva_codec_mode , t_sva_image_desc , const t_sva_dc_algo_configuration_params *);
++PUBLIC t_sva_error sva_DC_H264_GetMemoryNeeds( t_sva_service_instance_num , t_size *);
++PUBLIC t_sva_error sva_DC_H264_ProvideMemoryNeeds(t_sva_service_instance_num );
++PUBLIC t_sva_error sva_DC_H264_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id);
++PUBLIC t_sva_error sva_DC_H264_Close(t_sva_service_instance_num );
++PUBLIC t_sva_error sva_DC_H264_InitHeaderInfos(t_sva_service_instance_num );
++PUBLIC t_sva_error sva_DC_H264_SetHeaderInfos(t_sva_service_instance_num , t_sva_service_id ,t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *) ;
++PUBLIC t_sva_error sva_DC_H264_AssertEndOfBitstream(t_sva_service_instance_num , t_sva_service_id ) ;
++PUBLIC t_sva_error sva_DC_H264_Push(t_sva_service_instance_num , t_sva_buffer_type , t_sva_buffer_id ) ;
++PUBLIC t_sva_error sva_DC_H264_DispatchEOT(t_sva_service_instance_num ,t_sva_tm_subtask_id , t_sva_event_desc* ,t_sva_service_id ,t_uint32 , t_uint32 ,t_uint32 *,t_uint32 ,t_sva_buffer_list_id);
++PUBLIC t_sva_error sva_DC_H264_HandleFakeEvent( t_sva_tm_virtual_hw_event_id ,
++ t_sva_service_id ,
++ t_sva_tm_subtask_id ,
++ t_uint32 ,
++ t_uint32 ,
++ t_uint8 ,
++ t_uint32 *,
++ t_sva_event_desc *);
++PUBLIC t_sva_error sva_DC_H264_ResolveDependencies(t_sva_service_instance_num );
++PUBLIC t_bool sva_DC_H264_CheckInputDep(t_sva_service_instance_num);
++PUBLIC t_bool sva_DC_H264_CheckOutputDep(t_sva_service_instance_num);
++
++
++/* not usefull but needed to be existing */
++
++PUBLIC t_sva_error sva_DC_H264_FlushBitstreams(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_GetLastErrorType (t_sva_service_instance_num, t_uint16 *);
++PUBLIC t_sva_error sva_DC_H264_FlushFifos(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_DeleteFake(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *);
++PUBLIC t_size sva_DC_H264_GetOutputParamsSize(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *);
++PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitInstance(t_sva_service_instance_num instanceNum);
++
++
++
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif /* __cplusplus */
++
++
++
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c
@@ -0,0 +1,3101 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+ 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 */
+
+
+#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 */
+
+
+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h 2008-07-17 16:45:00.000000000 +0530
-@@ -0,0 +1,110 @@
-+/*---------------------------------------------------------------------------*/
-+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
-+/* information, STMicroelectronics reserves the right to license this */
-+/* software concurrently under separate license conditions. */
-+/* */
-+/* This program is free software; you can redistribute it and/or modify it */
-+/* under the terms of the GNU Lesser General Public License as published */
-+/* by the Free Software Foundation; either version 2.1 of the License, */
-+/* or (at your option)any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, but */
-+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-+/* the GNU Lesser General Public License for more details. */
-+/* */
-+/* You should have received a copy of the GNU Lesser General Public License */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVA_DC_H264_H
-+#define __INC_SVA_DC_H264_H
-+
-+#include "hcl_defs.h"
-+#include "sva_service.h"
-+#include "sva_dc_h264_dpb.h"
-+#include "sva_dc_h264_slicemap.h"
-+
-+
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+#ifdef __DEBUG
-+#define SVA_DC_H264_MAX_DBG_DEPTH 30
-+#define SVA_DC_H264_MAX_DBG_SLICESPERFRAME 9
-+#define SVA_DC_H264_MAX_DBG_EVENTS 12
-+#endif
-+
-+/* macros */
-+#define H264MIN(a,b) (((a)<(b))?a:b)
-+#define H264MAX(a,b) (((a)>(b))?a:b)
-+#define H264_MAX_UINT_16 65535
-+#define H264_MAX_SINT_32 2147483647
-+#define H264_MIN_SINT_32 -H264_MAX_SINT_32-1
-+#define H264_MAX_UINT_32 4294967295
-+
-+/* extracted from each slice headers of the frame and required to program vdc_h264_slice */
-+typedef t_sva_h264_dpb_params_slice t_sva_h264_params_slice;
-+
-+
-+/* used as parameter for SetHeaderInfo */
-+typedef struct
-+{ /* from active PPS */
-+ t_uint16 chromaQpIndex;
-+ t_uint16 constrIntraPredFlag;
-+ t_uint16 numRefIdxl0ActiveMinus1;
-+}t_sva_h264_active_pps;
-+
-+
-+/* extracted from active PPS and first slice Header, used to compute sliceMap */
-+typedef t_sva_h264_slicemap t_sva_h264_slicemap_info;
-+
-+
-+
-+/* public fonctions */
-+PUBLIC t_sva_error sva_DC_H264_Init( t_sva_service_instance_num , t_sva_codec_mode , t_sva_image_desc , const t_sva_dc_algo_configuration_params *);
-+PUBLIC t_sva_error sva_DC_H264_GetMemoryNeeds( t_sva_service_instance_num , t_size *);
-+PUBLIC t_sva_error sva_DC_H264_ProvideMemoryNeeds(t_sva_service_instance_num );
-+PUBLIC t_sva_error sva_DC_H264_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id);
-+PUBLIC t_sva_error sva_DC_H264_Close(t_sva_service_instance_num );
-+PUBLIC t_sva_error sva_DC_H264_InitHeaderInfos(t_sva_service_instance_num );
-+PUBLIC t_sva_error sva_DC_H264_SetHeaderInfos(t_sva_service_instance_num , t_sva_service_id ,t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *) ;
-+PUBLIC t_sva_error sva_DC_H264_AssertEndOfBitstream(t_sva_service_instance_num , t_sva_service_id ) ;
-+PUBLIC t_sva_error sva_DC_H264_Push(t_sva_service_instance_num , t_sva_buffer_type , t_sva_buffer_id ) ;
-+PUBLIC t_sva_error sva_DC_H264_DispatchEOT(t_sva_service_instance_num ,t_sva_tm_subtask_id , t_sva_event_desc* ,t_sva_service_id ,t_uint32 , t_uint32 ,t_uint32 *,t_uint32 ,t_sva_buffer_list_id);
-+PUBLIC t_sva_error sva_DC_H264_HandleFakeEvent( t_sva_tm_virtual_hw_event_id ,
-+ t_sva_service_id ,
-+ t_sva_tm_subtask_id ,
-+ t_uint32 ,
-+ t_uint32 ,
-+ t_uint8 ,
-+ t_uint32 *,
-+ t_sva_event_desc *);
-+PUBLIC t_sva_error sva_DC_H264_ResolveDependencies(t_sva_service_instance_num );
-+PUBLIC t_bool sva_DC_H264_CheckInputDep(t_sva_service_instance_num);
-+PUBLIC t_bool sva_DC_H264_CheckOutputDep(t_sva_service_instance_num);
-+
-+
-+/* not usefull but needed to be existing */
-+
-+PUBLIC t_sva_error sva_DC_H264_FlushBitstreams(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_GetLastErrorType (t_sva_service_instance_num, t_uint16 *);
-+PUBLIC t_sva_error sva_DC_H264_FlushFifos(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_DeleteFake(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *);
-+PUBLIC t_size sva_DC_H264_GetOutputParamsSize(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *);
-+PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitInstance(t_sva_service_instance_num instanceNum);
-+
-+
-+
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif /* __cplusplus */
-+
-+
-+
-+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h 2008-07-17 16:45:04.000000000 +0530
-@@ -0,0 +1,156 @@
-+/*---------------------------------------------------------------------------*/
-+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
-+/* information, STMicroelectronics reserves the right to license this */
-+/* software concurrently under separate license conditions. */
-+/* */
-+/* This program is free software; you can redistribute it and/or modify it */
-+/* under the terms of the GNU Lesser General Public License as published */
-+/* by the Free Software Foundation; either version 2.1 of the License, */
-+/* or (at your option)any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, but */
-+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-+/* the GNU Lesser General Public License for more details. */
-+/* */
-+/* You should have received a copy of the GNU Lesser General Public License */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVA_DC_H264_P_H
-+#define __INC_SVA_DC_H264_P_H
-+
-+#include "hcl_defs.h"
-+#include "sva_service.h"
-+#include "sva.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+
-+/* enum error : remains internal, used for debug */
-+typedef enum
-+{
-+ SVA_DC_H264_DPB_START_PICTURELOSS_NOT_SUPPORTED,
-+ SVA_DC_H264_DPB_START_MISSING_BUFFER_ERROR,
-+ SVA_DC_H264_DPB_START_ERROR,
-+ SVA_DC_H264_DPB_END_ERROR,
-+ SVA_DC_H264_DPB_PUSH_ERROR,
-+ SVA_DC_H264_PARAMIN_ERROR,
-+ SVA_DC_H264_LIST0_ERROR
-+}t_sva_dc_h264_error;
-+
-+
-+
-+typedef struct
-+{
-+ t_uint16 non_zero;
-+ t_uint16 BKType;
-+ t_sint16 mv[2];
-+}t_sva_h264_block4x4_info;
-+/* from t_block_info structure from ref code */
-+
-+typedef struct
-+{
-+ t_sint16 nslice; /* -1 not decoded */
-+ t_uint16 concealed;
-+ t_uint16 QP[2];
-+ t_uint16 reserved1;
-+ t_uint16 reserved2;
-+ t_uint16 reserved3;
-+ t_uint16 reserved4;
-+ t_sva_h264_block4x4_info block4x4Info[16];
-+} t_sva_h264_mblock_info;
-+
-+
-+/* from tps_h4d_param structure from ref code: */
-+typedef struct
-+{
-+ unsigned _0 : 2; unsigned A_l : 6;
-+ unsigned _1 : 2; unsigned B_l : 6;
-+ unsigned _2 : 2; unsigned A_c : 6;
-+ unsigned _3 : 2; unsigned B_c : 6;
-+
-+} t_sva_h264_ab_index;
-+
-+
-+
-+typedef struct
-+{
-+ unsigned _0 : 2; unsigned h0 : 3; unsigned v0 : 3;
-+ unsigned _1 : 2; unsigned h1 : 3; unsigned v1 : 3;
-+ unsigned _2 : 2; unsigned h2 : 3; unsigned v2 : 3;
-+ unsigned _3 : 2; unsigned h3 : 3; unsigned v3 : 3;
-+
-+} t_sva_h264_strength;
-+
-+
-+
-+typedef struct
-+{
-+ t_sva_h264_ab_index index[3];
-+ t_uint32 loc;
-+ t_sva_h264_strength bs[4];
-+
-+} t_sva_h264_h4d_param;
-+
-+
-+
-+
-+/* descriptor of internal variable*/
-+typedef struct{
-+ t_sva_codec_mode codecMode;
-+ t_uint16 picWidthInMbsMinus1;
-+ t_uint16 picHeightInMapUnitsMinus1;
-+ t_sva_video_decoder_algo_h264_configuration_params staticParams;
-+
-+ t_sva_dc_fifo_dep slicesDescBlockIdFifo; //BlockId Fifo
-+ t_sva_dc_fifo_dep sliceMapFifo; //Fifo of t_sva_h264_slicemap
-+
-+ /* vdc_internal_buf */
-+ t_size blockInfoSize;
-+ t_sva_block_id blockInfoId[SUBTASK_DEFAULT_NUMBER];
-+ t_system_address blockInfoAddr[SUBTASK_DEFAULT_NUMBER];
-+ t_sva_block_id blockSliceMapId[SUBTASK_DEFAULT_NUMBER];
-+ t_system_address blockSliceMapAddr[SUBTASK_DEFAULT_NUMBER];
-+ t_sva_block_id blockH4DId[SUBTASK_DEFAULT_NUMBER];
-+ t_system_address blockH4DAddr[SUBTASK_DEFAULT_NUMBER];
-+ /* vdc_frame_buf_out : addr_deblocking_param_buffer */
-+ t_sva_block_id blockDeblockId;
-+ t_system_address blockDeblockAddr;
-+
-+
-+ /* vdc_h264_slice */
-+ t_sva_block_id blockSlicesId[SUBTASK_DEFAULT_NUMBER];
-+ t_system_address blockSlicesAddr[SUBTASK_DEFAULT_NUMBER];
-+ t_uint32 currentNbSlices;
-+ t_sva_dc_h264_error h264Error;
-+
-+
-+ t_sva_h264_dpb_sps_utils spsForDpb;
-+ t_sva_h264_dpb_slice0_utils slice0ForDpb;
-+
-+
-+
-+#ifdef __DEBUG
-+ t_uint32 dbgSliceCounter;
-+ t_uint32 dbgSliceIndex;
-+ //t_sva_vdc_h264_slice slicesTrace[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_SLICESPERFRAME];
-+ t_uint32 dbgNbEvent;
-+ t_sva_event_desc eventTraces[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_EVENTS];
-+#endif
-+
-+ t_bool isToDo;
-+ t_sva_h264_slicemap_info sliceMap;
-+}t_sva_h264_desc;
-+
-+
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif /* __cplusplus */
-+
-+
-+
-+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c 2008-07-17 16:45:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c
@@ -0,0 +1,312 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+ 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 */
+#endif /* __cplusplus */
+
+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c 2008-07-17 16:45:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h
+@@ -0,0 +1,156 @@
++/*---------------------------------------------------------------------------*/
++/* © copyright STMicroelectronics, 2007. All rights reserved. For */
++/* information, STMicroelectronics reserves the right to license this */
++/* software concurrently under separate license conditions. */
++/* */
++/* This program is free software; you can redistribute it and/or modify it */
++/* under the terms of the GNU Lesser General Public License as published */
++/* by the Free Software Foundation; either version 2.1 of the License, */
++/* or (at your option)any later version. */
++/* */
++/* This program is distributed in the hope that it will be useful, but */
++/* WITHOUT ANY WARRANTY; without even the implied warranty of */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
++/* the GNU Lesser General Public License for more details. */
++/* */
++/* You should have received a copy of the GNU Lesser General Public License */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVA_DC_H264_P_H
++#define __INC_SVA_DC_H264_P_H
++
++#include "hcl_defs.h"
++#include "sva_service.h"
++#include "sva.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++
++/* enum error : remains internal, used for debug */
++typedef enum
++{
++ SVA_DC_H264_DPB_START_PICTURELOSS_NOT_SUPPORTED,
++ SVA_DC_H264_DPB_START_MISSING_BUFFER_ERROR,
++ SVA_DC_H264_DPB_START_ERROR,
++ SVA_DC_H264_DPB_END_ERROR,
++ SVA_DC_H264_DPB_PUSH_ERROR,
++ SVA_DC_H264_PARAMIN_ERROR,
++ SVA_DC_H264_LIST0_ERROR
++}t_sva_dc_h264_error;
++
++
++
++typedef struct
++{
++ t_uint16 non_zero;
++ t_uint16 BKType;
++ t_sint16 mv[2];
++}t_sva_h264_block4x4_info;
++/* from t_block_info structure from ref code */
++
++typedef struct
++{
++ t_sint16 nslice; /* -1 not decoded */
++ t_uint16 concealed;
++ t_uint16 QP[2];
++ t_uint16 reserved1;
++ t_uint16 reserved2;
++ t_uint16 reserved3;
++ t_uint16 reserved4;
++ t_sva_h264_block4x4_info block4x4Info[16];
++} t_sva_h264_mblock_info;
++
++
++/* from tps_h4d_param structure from ref code: */
++typedef struct
++{
++ unsigned _0 : 2; unsigned A_l : 6;
++ unsigned _1 : 2; unsigned B_l : 6;
++ unsigned _2 : 2; unsigned A_c : 6;
++ unsigned _3 : 2; unsigned B_c : 6;
++
++} t_sva_h264_ab_index;
++
++
++
++typedef struct
++{
++ unsigned _0 : 2; unsigned h0 : 3; unsigned v0 : 3;
++ unsigned _1 : 2; unsigned h1 : 3; unsigned v1 : 3;
++ unsigned _2 : 2; unsigned h2 : 3; unsigned v2 : 3;
++ unsigned _3 : 2; unsigned h3 : 3; unsigned v3 : 3;
++
++} t_sva_h264_strength;
++
++
++
++typedef struct
++{
++ t_sva_h264_ab_index index[3];
++ t_uint32 loc;
++ t_sva_h264_strength bs[4];
++
++} t_sva_h264_h4d_param;
++
++
++
++
++/* descriptor of internal variable*/
++typedef struct{
++ t_sva_codec_mode codecMode;
++ t_uint16 picWidthInMbsMinus1;
++ t_uint16 picHeightInMapUnitsMinus1;
++ t_sva_video_decoder_algo_h264_configuration_params staticParams;
++
++ t_sva_dc_fifo_dep slicesDescBlockIdFifo; //BlockId Fifo
++ t_sva_dc_fifo_dep sliceMapFifo; //Fifo of t_sva_h264_slicemap
++
++ /* vdc_internal_buf */
++ t_size blockInfoSize;
++ t_sva_block_id blockInfoId[SUBTASK_DEFAULT_NUMBER];
++ t_system_address blockInfoAddr[SUBTASK_DEFAULT_NUMBER];
++ t_sva_block_id blockSliceMapId[SUBTASK_DEFAULT_NUMBER];
++ t_system_address blockSliceMapAddr[SUBTASK_DEFAULT_NUMBER];
++ t_sva_block_id blockH4DId[SUBTASK_DEFAULT_NUMBER];
++ t_system_address blockH4DAddr[SUBTASK_DEFAULT_NUMBER];
++ /* vdc_frame_buf_out : addr_deblocking_param_buffer */
++ t_sva_block_id blockDeblockId;
++ t_system_address blockDeblockAddr;
++
++
++ /* vdc_h264_slice */
++ t_sva_block_id blockSlicesId[SUBTASK_DEFAULT_NUMBER];
++ t_system_address blockSlicesAddr[SUBTASK_DEFAULT_NUMBER];
++ t_uint32 currentNbSlices;
++ t_sva_dc_h264_error h264Error;
++
++
++ t_sva_h264_dpb_sps_utils spsForDpb;
++ t_sva_h264_dpb_slice0_utils slice0ForDpb;
++
++
++
++#ifdef __DEBUG
++ t_uint32 dbgSliceCounter;
++ t_uint32 dbgSliceIndex;
++ //t_sva_vdc_h264_slice slicesTrace[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_SLICESPERFRAME];
++ t_uint32 dbgNbEvent;
++ t_sva_event_desc eventTraces[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_EVENTS];
++#endif
++
++ t_bool isToDo;
++ t_sva_h264_slicemap_info sliceMap;
++}t_sva_h264_desc;
++
++
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif /* __cplusplus */
++
++
++
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c
@@ -0,0 +1,2126 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+}
+
+// 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 */
+
+#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 */
+ 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 */
+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 */
+ }
+
+ SVA_FreeBuffer(mp4Desc[instanceNum].lastFwdRefImageBufferId);
-+
++
+ DELETE_FIFO(mp4Desc[instanceNum].fakeBitstreamFifo);
+
+ return SVA_OK;
+}
+
+// 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 */
+
+#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 */
+
+
+
-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 */
+
+#endif
+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h 2008-07-17 16:44:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h
+@@ -0,0 +1,18 @@
++/*---------------------------------------------------------------------------*/
++/* © copyright STMicroelectronics, 2007. All rights reserved. For */
++/* information, STMicroelectronics reserves the right to license this */
++/* software concurrently under separate license conditions. */
++/* */
++/* This program is free software; you can redistribute it and/or modify it */
++/* under the terms of the GNU Lesser General Public License as published */
++/* by the Free Software Foundation; either version 2.1 of the License, */
++/* or (at your option)any later version. */
++/* */
++/* This program is distributed in the hope that it will be useful, but */
++/* WITHOUT ANY WARRANTY; without even the implied warranty of */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
++/* the GNU Lesser General Public License for more details. */
++/* */
++/* You should have received a copy of the GNU Lesser General Public License */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
++/*---------------------------------------------------------------------------*/
+\ No newline at end of file
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h
@@ -0,0 +1,135 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+
+#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 */
+
+
+
-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 */
+
+#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 */
+ 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 */
+
+#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 */
+#endif /* __cplusplus */
+
+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h 2008-07-17 16:44:54.000000000 +0530
-@@ -0,0 +1,18 @@
-+/*---------------------------------------------------------------------------*/
-+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
-+/* information, STMicroelectronics reserves the right to license this */
-+/* software concurrently under separate license conditions. */
-+/* */
-+/* This program is free software; you can redistribute it and/or modify it */
-+/* under the terms of the GNU Lesser General Public License as published */
-+/* by the Free Software Foundation; either version 2.1 of the License, */
-+/* or (at your option)any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, but */
-+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-+/* the GNU Lesser General Public License for more details. */
-+/* */
-+/* You should have received a copy of the GNU Lesser General Public License */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+/*---------------------------------------------------------------------------*/
-\ No newline at end of file
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c 2008-07-17 16:45:11.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c
@@ -0,0 +1,2044 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+}
+
+// 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 */
+
+#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 */
+ 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 */
+//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 */
+ 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 */
+#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 */
+
+#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 */
+}
+
+ /* 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 */
+
+#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 */
+
+#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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 */
+
+#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 */
+#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 */
+
+#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 */
+
+ 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 */
+
+#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 */
+#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 */
+
+ 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 */
+
+#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 */
+#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 */
+
+
+/* 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 */
+#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 */
+
+/* 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 */
+
+#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 */
+
+#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 */
+}
+
+
-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 */
+
+#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 */
+
+#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 */
+#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 */
+
+#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 */
+
+#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 */
+
+#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 */
+
+#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 */
+#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 */
+
+#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 */
+
+#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 */
+
+#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 */
+
+#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 */
+
+#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 */
+#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 */
+
+#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 */
+#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 */
+
+#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 */
+} 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 */
+
+#endif /* __INC_HV_FM_H */
+/* End of file - hv_fwMgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h 2008-07-17 16:44:29.000000000 +0530
-@@ -0,0 +1,193 @@
-+/*---------------------------------------------------------------------------*/
-+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
-+/* information, STMicroelectronics reserves the right to license this */
-+/* software concurrently under separate license conditions. */
-+/* */
-+/* This program is free software; you can redistribute it and/or modify it */
-+/* under the terms of the GNU Lesser General Public License as published */
-+/* by the Free Software Foundation; either version 2.1 of the License, */
-+/* or (at your option)any later version. */
-+/* */
-+/* This program is distributed in the hope that it will be useful, but */
-+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
-+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-+/* the GNU Lesser General Public License for more details. */
-+/* */
-+/* You should have received a copy of the GNU Lesser General Public License */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVAP_H
-+#define __INC_SVAP_H
-+
-+#include "hcl_defs.h"
-+
-+/******************************************************************************/
-+/* Constants definitions */
-+/******************************************************************************/
-+/*
-+ * Define various conditonnal compilation flags in order to include or not any SW workarounds
-+ */
-+/*#define WORK_AROUND_AHB*/
-+
-+/*
-+ * Define the maximum number of error defined per module
-+ */
-+#define SVA_MODULE_ERROR_RANGE 0x20
-+
-+/*
-+ * Define an Id related to each module of the SVA HCL
-+ * The Id = 1 is reserved for SVA HCL itself
-+ */
-+typedef enum {
-+ SVA_EM_ID = 2, /* Events Mgt */
-+ SVA_MM_ID, /* Memory Mgt */
-+ SVA_BM_ID, /* Buffers Mgt */
-+ SVA_BLM_ID, /* Buffers ListMgt */
-+ SVA_TM_ID, /* Tasks Mgt */
-+ SVA_FM_ID, /* Firmware Mgt */
-+ SVA_TI_ID, /* Time Mgt */
-+ SVA_VP_ID, /* Video Pipeline */
-+ SVA_FF_ID, /* FIFO macros */
-+ SVA_IN_ID, /* Internal Needs Mgt */
-+ SVA_SV_ID, /* Common Service */
-+ SVA_DP_ID, /* Display Service */
-+ SVA_DC_ID, /* Decode Service */
-+ SVA_EC_ID, /* Encode Service */
-+ SVA_GB_ID, /* Grab Service */
-+ SVA_DC_ERC_ID, /* Decode Error Concealment */
-+ SVA_DC_MP4_ID, /* Decode MPEG4 Algo */
-+ SVA_DC_H263_ID, /* Decode H263 Algo */
-+ SVA_DC_H264_ID, /* Decode H263 Algo */
-+ SVA_EC_BRC_ID, /* Encode Bit Rate Control */
-+ SVA_EC_MP4_ID, /* Encode MPEG4 Algo */
-+ SVA_EC_H263_ID, /* Encode H263 Algo */
-+ SVA_EC_H264_ID, /* Encode H264 Algo */
-+ SVA_EC_STAB_ID, /* Encode Stabilization */
-+ SVA_SEC_JPEG_ID, /* Still Encode JPEG ALgo */
-+ SVA_SEC_ID, /* still Encode service */
-+ SVA_TV_ID /* TVO Service */
-+} sva_module_id;
-+
-+/* ************************** CONFIGURATION PART ************************** */
-+
-+
-+//typedef t_uint32 t_sva_fw_id;
-+
-+
-+typedef struct {
-+ t_uint32 cfg_psa; /* Subtask parameter Start Address register */
-+ t_uint32 cfg_pea; /* Subtask parameter Stop Address register */
-+ t_uint32 cfg_ice; /* Idle Cycle Enable register */
-+ t_uint32 cfg_csc; /* CCP synchronization codes register */
-+ t_uint32 cfg_cgc; /* clock gating control register */
-+ t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
-+ t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
-+ t_uint32 cfg_irp_rw; /* status of the current rw operation */
-+ t_uint32 cfg_irp_error; /* error code */
-+ t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
-+ t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
-+ t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
-+ t_uint32 cfg_clk; /* Clock generation register */
-+ t_uint32 ckg_cken; /* added*/
-+ t_uint32 cfg_tim; /* Timer Initialization value register */
-+ t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */
-+ t_uint32 cfg_isr; /* Global Interrupt status register */
-+ t_uint32 cfg_imr; /* Global Interrupt mask register */
-+// t_uint32 wasDeepSleepEntered;
-+ t_uint32 temp_idn_frv;
-+ t_uint32 fwId;
-+ t_uint32 sva_context_magic_number;
-+} t_sva_config_regs_mapping1;
-+
-+#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
-+
-+#define SVA_EM_LAST_ERROR (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EM_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_MM_LAST_ERROR (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_MM_FIRST_INFO (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BM_LAST_ERROR (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BM_FIRST_INFO (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BLM_LAST_ERROR (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BLM_FIRST_INFO (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TM_LAST_ERROR (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TM_FIRST_INFO (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FM_LAST_ERROR (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FM_FIRST_INFO (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TI_LAST_ERROR (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TI_FIRST_INFO (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FF_LAST_ERROR (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FF_FIRST_INFO (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_IN_LAST_ERROR (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_IN_FIRST_INFO (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SV_LAST_ERROR (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SV_FIRST_INFO (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DP_LAST_ERROR (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DP_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_LAST_ERROR (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_FIRST_INFO (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_LAST_ERROR (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_FIRST_INFO (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_GB_LAST_ERROR (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_GB_FIRST_INFO (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H263_LAST_ERROR (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H263_FIRST_INFO (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H264_LAST_ERROR (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H264_FIRST_INFO (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+
-+#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H263_LAST_ERROR (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H263_FIRST_INFO (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H264_LAST_ERROR (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H264_FIRST_INFO (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_STAB_LAST_ERROR (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_STAB_FIRST_INFO (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_JPEG_LAST_ERROR (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_JPEG_FIRST_INFO (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_LAST_ERROR (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_FIRST_INFO (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TV_LAST_ERROR (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TV_FIRST_ERROR (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+/******************************************************************************/
-+/* Types definitions */
-+/******************************************************************************/
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif /* __cplusplus */
-+
-+#endif /* __INC_SVAP_H */
-+/* End of file - hvP.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h 2008-07-17 16:44:26.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h
@@ -0,0 +1,337 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+
+#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 */
+
+#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 */
+
+#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 */
+#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 */
+#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 */
+
+#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 */
+
+#endif /* __INC_SVA_TVO_H */
+/* End of file - sva_tvo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h 2008-07-17 16:44:29.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h
+@@ -0,0 +1,193 @@
++/*---------------------------------------------------------------------------*/
++/* © copyright STMicroelectronics, 2007. All rights reserved. For */
++/* information, STMicroelectronics reserves the right to license this */
++/* software concurrently under separate license conditions. */
++/* */
++/* This program is free software; you can redistribute it and/or modify it */
++/* under the terms of the GNU Lesser General Public License as published */
++/* by the Free Software Foundation; either version 2.1 of the License, */
++/* or (at your option)any later version. */
++/* */
++/* This program is distributed in the hope that it will be useful, but */
++/* WITHOUT ANY WARRANTY; without even the implied warranty of */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
++/* the GNU Lesser General Public License for more details. */
++/* */
++/* You should have received a copy of the GNU Lesser General Public License */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVAP_H
++#define __INC_SVAP_H
++
++#include "hcl_defs.h"
++
++/******************************************************************************/
++/* Constants definitions */
++/******************************************************************************/
++/*
++ * Define various conditonnal compilation flags in order to include or not any SW workarounds
++ */
++/*#define WORK_AROUND_AHB*/
++
++/*
++ * Define the maximum number of error defined per module
++ */
++#define SVA_MODULE_ERROR_RANGE 0x20
++
++/*
++ * Define an Id related to each module of the SVA HCL
++ * The Id = 1 is reserved for SVA HCL itself
++ */
++typedef enum {
++ SVA_EM_ID = 2, /* Events Mgt */
++ SVA_MM_ID, /* Memory Mgt */
++ SVA_BM_ID, /* Buffers Mgt */
++ SVA_BLM_ID, /* Buffers ListMgt */
++ SVA_TM_ID, /* Tasks Mgt */
++ SVA_FM_ID, /* Firmware Mgt */
++ SVA_TI_ID, /* Time Mgt */
++ SVA_VP_ID, /* Video Pipeline */
++ SVA_FF_ID, /* FIFO macros */
++ SVA_IN_ID, /* Internal Needs Mgt */
++ SVA_SV_ID, /* Common Service */
++ SVA_DP_ID, /* Display Service */
++ SVA_DC_ID, /* Decode Service */
++ SVA_EC_ID, /* Encode Service */
++ SVA_GB_ID, /* Grab Service */
++ SVA_DC_ERC_ID, /* Decode Error Concealment */
++ SVA_DC_MP4_ID, /* Decode MPEG4 Algo */
++ SVA_DC_H263_ID, /* Decode H263 Algo */
++ SVA_DC_H264_ID, /* Decode H263 Algo */
++ SVA_EC_BRC_ID, /* Encode Bit Rate Control */
++ SVA_EC_MP4_ID, /* Encode MPEG4 Algo */
++ SVA_EC_H263_ID, /* Encode H263 Algo */
++ SVA_EC_H264_ID, /* Encode H264 Algo */
++ SVA_EC_STAB_ID, /* Encode Stabilization */
++ SVA_SEC_JPEG_ID, /* Still Encode JPEG ALgo */
++ SVA_SEC_ID, /* still Encode service */
++ SVA_TV_ID /* TVO Service */
++} sva_module_id;
++
++/* ************************** CONFIGURATION PART ************************** */
++
++
++//typedef t_uint32 t_sva_fw_id;
++
++
++typedef struct {
++ t_uint32 cfg_psa; /* Subtask parameter Start Address register */
++ t_uint32 cfg_pea; /* Subtask parameter Stop Address register */
++ t_uint32 cfg_ice; /* Idle Cycle Enable register */
++ t_uint32 cfg_csc; /* CCP synchronization codes register */
++ t_uint32 cfg_cgc; /* clock gating control register */
++ t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
++ t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
++ t_uint32 cfg_irp_rw; /* status of the current rw operation */
++ t_uint32 cfg_irp_error; /* error code */
++ t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
++ t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
++ t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
++ t_uint32 cfg_clk; /* Clock generation register */
++ t_uint32 ckg_cken; /* added*/
++ t_uint32 cfg_tim; /* Timer Initialization value register */
++ t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */
++ t_uint32 cfg_isr; /* Global Interrupt status register */
++ t_uint32 cfg_imr; /* Global Interrupt mask register */
++// t_uint32 wasDeepSleepEntered;
++ t_uint32 temp_idn_frv;
++ t_uint32 fwId;
++ t_uint32 sva_context_magic_number;
++} t_sva_config_regs_mapping1;
++
++#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
++
++#define SVA_EM_LAST_ERROR (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EM_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_MM_LAST_ERROR (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_MM_FIRST_INFO (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BM_LAST_ERROR (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BM_FIRST_INFO (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BLM_LAST_ERROR (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BLM_FIRST_INFO (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TM_LAST_ERROR (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TM_FIRST_INFO (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FM_LAST_ERROR (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FM_FIRST_INFO (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TI_LAST_ERROR (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TI_FIRST_INFO (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FF_LAST_ERROR (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FF_FIRST_INFO (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_IN_LAST_ERROR (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_IN_FIRST_INFO (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SV_LAST_ERROR (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SV_FIRST_INFO (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DP_LAST_ERROR (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DP_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_LAST_ERROR (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_FIRST_INFO (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_LAST_ERROR (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_FIRST_INFO (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_GB_LAST_ERROR (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_GB_FIRST_INFO (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H263_LAST_ERROR (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H263_FIRST_INFO (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H264_LAST_ERROR (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H264_FIRST_INFO (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++
++#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H263_LAST_ERROR (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H263_FIRST_INFO (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H264_LAST_ERROR (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H264_FIRST_INFO (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_STAB_LAST_ERROR (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_STAB_FIRST_INFO (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_JPEG_LAST_ERROR (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_JPEG_FIRST_INFO (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_LAST_ERROR (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_FIRST_INFO (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TV_LAST_ERROR (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TV_FIRST_ERROR (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++/******************************************************************************/
++/* Types definitions */
++/******************************************************************************/
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif /* __cplusplus */
++
++#endif /* __INC_SVAP_H */
++/* End of file - hvP.h */
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h
@@ -0,0 +1,1725 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+#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 */
+#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 */
+
+
+// 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 */
+#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 */
+
+#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 */
+} /* 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 */
+
+#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 */
+
+#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 */
+/* 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 */
+
+#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 */
+
+#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 */
+} 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 */
+}
+
+// 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 */
+
+#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 */
+
+#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 */
+
+ 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 */
+
+#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 */
+
+#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 */
+}
+
+
-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 */
+
+#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 */
+
+#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 */
+
+#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 */
+}
+
+
-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 */
+
+#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 */
+
+#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 */
+
+/* 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 */
+
+#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 */
+
+#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 */
+
+#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 */
+ 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 */
+#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 */
+
+#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 */
+ 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 */
+
+#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 */
+
+
+// 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 */
+
+#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 */
+
+#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 */
+
+// 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 */
+#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 */
+
+#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 */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/*---------------------------------------------------------------------------*/
+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c 2008-07-17 16:43:48.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c
@@ -0,0 +1,2478 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+
+ 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 */
+
+#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 */
+
+#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))
+
+clean :
+ $(MAKE) -C ../../linux-2.6.20 M=`pwd` clean; rm -f $(hloader_obj)
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c 2008-11-24 14:06:32.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c
@@ -0,0 +1,565 @@
+/*---------------------------------------------------------------------------*/\r
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */\r
+\r
+module_init(nomadik_ogles_init);\r
+module_exit(nomadik_ogles_exit);\r
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h 2008-10-07 12:20:09.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h
@@ -0,0 +1,65 @@
+/*---------------------------------------------------------------------------*/\r
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */\r
+MODULE_LICENSE("GPL");\r
+MODULE_AUTHOR("Jayarami reddy <jayarami.reddy@stnwireless.com>");\r
+MODULE_DESCRIPTION(" This module is a OGLES module !!");\r
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h 2008-10-07 12:20:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h
@@ -0,0 +1,56 @@
+/*---------------------------------------------------------------------------*/\r
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */\r
+MODULE_DESCRIPTION(" This module is a OGLES module !!");\r
+\r
+#endif //OGL_IOCTL_H\r
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile
---- linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile 2008-08-12 22:56:07.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile
@@ -0,0 +1,20 @@
+#KERNEL_PATH := ../../../../../linux-2.6.20
+EXTRA_CFLAGS_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
+EXTRA_CFLAGS := $(EXTRA_CFLAGS_NAME) -D__arm -I$(src)/ -I$(src)/../hcl/include/ -I$(src)/../hcl/saa/ -I$(src)/../hcl/hloader/
+#
+#all:
-+# $(MAKE) -C $(KERNEL_PATH) M=`pwd`
-+#
++# $(MAKE) -C $(KERNEL_PATH) M=`pwd`
++#
+#
+obj-$(CONFIG_NOMADIK_SAA) += nmdkmod_SAA.o nmdkmod_fwload.o
+
+
+#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. */
+ 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");
+
+ up(&fw_desc->sem);
+ complete(&fw_desc->completion);
-+
++
+ return fw_desc->fw_size;
+}
+
+ 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) {
+
+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. */
+/*along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/*--------------------------------------------------------------------------------------------------*/
+
-+#ifndef _NOMADIK_FWLOAD_H
++#ifndef _NOMADIK_FWLOAD_H
+#define _NOMADIK_FWLOAD_H
+
+/* Debugging stuff */
+#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;
+};
+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. */
+#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)
+{
+ 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);
+
+#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
+
+
+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. */
+#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. */
+*******************************************************************/
+
+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;
+ unsigned char mix_with_playback;
+ saa_codec_tone_wave waveShape;
+ unsigned long* reserved2;
-+
++
+} saa_codec_tonegenerator_struct;
+
+/* audiocodec frequnecy setting structure */
+ 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 {
+ 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) */
+ t_uint32 count;
+ t_uint32 address;
+ saa_sample_freq freq;
-+
++
+} saa_samplecount_struct ;
+
+/* Version strcut of saa and saa-hcl */
+/* 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)
+#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)
+#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)
+
+
+
-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)
+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
+
+#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)
+
+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. */
+
+
+#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. */
+
+
+
-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. */
+MODULE_AUTHOR ("Melwyn LOBO <melwyn.lobo@st.com>");
+
+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h 2008-07-17 16:43:38.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h
@@ -0,0 +1,153 @@
+/*--------------------------------------------------------------------------------------------------*/
+/*© copyright STMicroelectronics, 2007. */
+ 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. */
+ ,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 {
+ 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 {
+ 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) {
+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. */
+ __u16 sensor_aoi_x;
+ __u16 sensor_aoi_y;
+ __u16 prescale_factor;
-+
++
+};
+
+struct sva_videodecoder_info {
+#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. */
+ 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. */
+
+
+#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. */
+}
+
+
-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. */
+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. */
+ 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. */
+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.
+ *-----------------------------------------------------------------------------
+ *
+#include "platform_os.h"
+
+/*-----------------------------------------------------------------------------
-+ * Type definition
++ * Type definition
+ *---------------------------------------------------------------------------*/
+typedef unsigned char t_uint8;
+typedef signed char t_sint8;
+
+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;
+
+/*
+ * 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 ,
+ 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,
+ HCL_FREQ_22MHZ,
+ HCL_FREQ_24MHZ,
+ HCL_FREQ_48MHZ
-+} t_frequency;
++} t_frequency;
+
+
+
+
+
+/*-----------------------------------------------------------------------------
-+ * Keyword definition
++ * Keyword definition
+ *---------------------------------------------------------------------------*/
+#define PUBLIC /* Extern by default */
+#define PRIVATE static
+#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
+#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1)
+#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2)
+#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3)
-+
++
+/*-----------------------------------------------------------------------------
+ * Halfword shift definition
+ *---------------------------------------------------------------------------*/
+ *---------------------------------------------------------------------------*/
+ #define ONE_KB (1024)
+ #define ONE_MB (ONE_KB * ONE_KB)
-+
-+
++
++
+/*-----------------------------------------------------------------------------
+ * Address translation macros declaration
+ *---------------------------------------------------------------------------*/
+#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. */
+
+
+#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. */
+
+
+
-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. */
+ __u16 sensor_aoi_x;
+ __u16 sensor_aoi_y;
+ __u16 prescale_factor;
-+
++
+};
+
+struct sva_videodecoder_info {
+#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. */
+
+
+#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. */
+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
+
+/*
+ * 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 */
+
+#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 */
+MODULE_AUTHOR("Melwyn LOBO <melwyn.lobo@st.com>");
+
+
-diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.h ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.h
---- linux-2.6.20/drivers/media/video/v4l2-nomadik.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.h 2008-07-17 16:42:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/v4l2-nomadik.h
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------*/
+/* © copyright STMicroelectronics, 2007. All rights reserved. For */
+int sva_service_update(struct sva_device_open *open, struct sva_update_service *update);
+
+
-diff -Nauprw linux-2.6.20/drivers/misc/batt-nomadik.c ../new/linux-2.6.20/drivers/misc/batt-nomadik.c
---- linux-2.6.20/drivers/misc/batt-nomadik.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/batt-nomadik.c 2008-10-20 13:38:12.000000000 +0530
+--- linux-2.6.20.orig/drivers/misc/Kconfig
++++ linux-2.6.20/drivers/misc/Kconfig
+@@ -1,11 +1,33 @@
+ #
+ # Misc strange devices
+ #
+
++# depends on ARCH_NOMADIK NOMADIK_SSP NOMADIK_GPIO
++
+ menu "Misc devices"
+
++
++config STMPE_NOMADIK
++ tristate "Port expander driver for Nomadik board"
++ depends on NOMADIK_NHK15
++ help
++ Say Y here if you have a port expander in your platform.
++
++config SIF_NOMADIK
++ tristate "Display protocol driver for nhk15"
++ depends on NOMADIK_NHK15
++ help
++ Say Y here if you want to change the gamma, brightness and contrast values
++ for the display
++
++config ETM_NOMADIK
++ tristate "ETM support nhk15"
++ depends on NOMADIK_NHK15
++ help
++ Say Y here if you want ETM support for debugging.
++
+ config IBM_ASM
+ tristate "Device driver for IBM RSA service processor"
+ depends on X86 && PCI && EXPERIMENTAL
+ ---help---
+ This option enables device driver support for in-band access to the
+@@ -86,6 +108,11 @@ config MSI_LAPTOP
+ More information about this driver is available at
+ <http://0pointer.de/lennart/tchibo.html>.
+
+ If you have an MSI S270 laptop, say Y or M here.
+
++config BATT_NOMADIK
++ tristate "Battery charger driver for Nomadik board"
++ depends on NOMADIK_NHK15
++ help
++ Say Y here if you have a port expander in your platform.
+ endmenu
+--- linux-2.6.20.orig/drivers/misc/Makefile
++++ linux-2.6.20/drivers/misc/Makefile
+@@ -8,5 +8,9 @@ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
+ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
+ obj-$(CONFIG_LKDTM) += lkdtm.o
+ obj-$(CONFIG_TIFM_CORE) += tifm_core.o
+ obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
+ obj-$(CONFIG_SGI_IOC4) += ioc4.o
++obj-$(CONFIG_STMPE_NOMADIK) += pexp-nomadik.o
++obj-$(CONFIG_SIF_NOMADIK) += sif-nomadik.o
++obj-$(CONFIG_ETM_NOMADIK) += etm-nomadik.o
++obj-$(CONFIG_BATT_NOMADIK) += batt-nomadik.o
+\ No newline at end of file
+--- /dev/null
++++ linux-2.6.20/drivers/misc/batt-nomadik.c
@@ -0,0 +1,1307 @@
+/*\r
+ * Overview:\r
+module_init(nomadik_stcharg_init);\r
+module_exit(nomadik_stcharg_exit);\r
+\r
-diff -Nauprw linux-2.6.20/drivers/misc/etm-nomadik.c ../new/linux-2.6.20/drivers/misc/etm-nomadik.c
---- linux-2.6.20/drivers/misc/etm-nomadik.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/etm-nomadik.c 2008-11-19 16:47:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/misc/etm-nomadik.c
@@ -0,0 +1,207 @@
+/*
+ * Overview:
+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:
+#include <asm/arch/pexp.h>
+#include <asm/arch/i2c.h>
+
-+#define DEBUG 0
++#define DEBUG 0
+
+
+/*
+ Internal defines
+*/
+
-+#define STMPE2401_WAIT_RESET_TIMEOUT 100
++#define STMPE2401_WAIT_RESET_TIMEOUT 100
+#define STMPE2401_I2C_TIMEOUT 1000
+
+/*STMP interrupt numbers*/
+#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*/
+#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
+#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*/
+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
+ 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)
+ return -EFAULT;
+
+ switch (cmd) {
-+
++
+ case STMPE_SET_BACKLIGHT:
+ copy_from_user(&bklight ,argp, sizeof(int));
+ if (bklight < 0 || bklight > 255 ) {
+/**
+ * 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.
+ */
+
+/**
+ * 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.
+ 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) {
+ }
+ /*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;
+
+ //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;
+ 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;
+ 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;
+ }
+ 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
+ */
+ 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;
+}
+
+*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*/
+ /*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)
+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)
+}
+
+/*
-+* This function configure the STMPE2401 gpio
++* This function configure the STMPE2401 gpio
+* Parameter
+* stmpeId = index of the device (0-3)
+* config = configuration structure
+ uint32 tempLong;
+ uint32 nByte;
+ uint8 tempByte;
-+
++
+ retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL );
+ if(retval != STMPE2401_OK)
+ {
-+ return retval;
++ return retval;
+ }
+ Devices[stmpeId].Gpio = *config;
-+
++
+ /*fill the temp buffer in the same order of STMPE internal register
+ "GPSR_Msb_Index" is the first, "GPAFR_L_Lsb_Index" the last
+ */
-+
-+ /*Output_State
++
++ /*Output_State
+ based on <Output_State> and <Direction>
+ */
+ tempLong = config->Output_State;
+ /*tempLong &= Direction;*/ /*remove input pin [..TBD..]*/
+
+ /*I2C slave internal address*/
-+ tempBuffer[0] = GPSR_Msb_Index;
-+
++ tempBuffer[0] = GPSR_Msb_Index;
++
+ tempBuffer[1] = LONG_TO_MSB(tempLong);
+ tempBuffer[2] = LONG_TO_CSB(tempLong);
+ tempBuffer[3] = LONG_TO_LSB(tempLong);
-+
++
+ tempLong = ~config->Output_State;
-+
++
+ tempBuffer[4] = LONG_TO_MSB(tempLong);
+ tempBuffer[5] = LONG_TO_CSB(tempLong);
+ tempBuffer[6] = LONG_TO_LSB(tempLong);
-+
++
+ /*Direction configuration*/
+ tempBuffer[7] = LONG_TO_MSB(config->Direction);
+ tempBuffer[8] = LONG_TO_CSB(config->Direction);
+ tempBuffer[9] = LONG_TO_LSB(config->Direction);
-+
++
+ /*Edge Detect Status register*/
+ tempBuffer[10] = LONG_TO_MSB(config->EdgeDetect);
+ tempBuffer[11] = LONG_TO_CSB(config->EdgeDetect);
+ tempBuffer[12] = LONG_TO_LSB(config->EdgeDetect);
-+
++
+ /*Rising Edge register*/
+ tempBuffer[13] = LONG_TO_MSB(config->RisingEdge);
+ tempBuffer[14] = LONG_TO_CSB(config->RisingEdge);
+ tempBuffer[15] = LONG_TO_LSB(config->RisingEdge);
-+
++
+ /*Falling Edge register*/
+ tempBuffer[16] = LONG_TO_MSB(config->FallingEdge);
+ tempBuffer[17] = LONG_TO_CSB(config->FallingEdge);
+ tempBuffer[18] = LONG_TO_LSB(config->FallingEdge);
-+
++
+ /*Pull Up register*/
-+ tempBuffer[19] = LONG_TO_MSB(config->PullUp);
++ tempBuffer[19] = LONG_TO_MSB(config->PullUp);
+ tempBuffer[20] = LONG_TO_CSB(config->PullUp);
+ tempBuffer[21] = LONG_TO_LSB(config->PullUp);
-+
++
+ /*Pull Down register*/
+ tempBuffer[22] = LONG_TO_MSB(config->PullDown);
+ tempBuffer[23] = LONG_TO_CSB(config->PullDown);
+ 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++)
+}
+
+
-+/*
++/*
+*This function read STMPE2401 gpio configuration and save it on *config
+* Parameter
+* stmpeId = index of the device (0-3)
+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));*/
+
+ 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)
+ else
+ {
+ /*invalid value*/
-+ retval = STMPE2401_BAD_PARAMETER;
-+ return retval;
++ retval = STMPE2401_BAD_PARAMETER;
++ return retval;
+ }
-+
++
+ if(PinIndex < 8)
+ {
+ /*XXX_Lsb_Index*/
+ 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;
+ 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;
+{
+ 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;
+}
+
+/*
+ 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:
+ 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;
+}
+
+/*
+{
+ 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
+{
+ 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;
+}
+
+/*
+ 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
+*/
+ 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:
+ 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;
+}
+
+/*
+ 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
+ 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)
+ {
+ 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)
+}
+
+
-+/*
++/*
+ This function init selected pwm channel
+ MUST be called after GPIO initializzation.
+
+ 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)
+ {
+ {
+ 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)
+ {
+ {
+ 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)
+ {
+ 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)
+ 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
+ */
+ delta = Devices[stmpeId].Pwm.PwmValue - Value;
+ sign = -1;
+ }
-+
++
+ if(Devices[stmpeId].Pwm.PwmValue == 0)
+ {
+ Istructions[0] = SMAX_ISTRUCTION;
+ }
+ /*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
+ {
+ len++;
+ }
+ retval = STMPE2401_SetPwmIstructions( stmpeId, channel, Istructions, len);
-+
++
+ if(retval == STMPE2401_OK)
+ {
+ Devices[stmpeId].Pwm.PwmValue = Value;
+ {
+ Devices[stmpeId].Pwm.PwmValue = 0;
+ }
-+
++
+ return retval;
-+}
++}
+
+/*
+ This function write end execute the pwm microcode passed by "*Istructions"
+ 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)
+ {
+ 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);
+ }
+ 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);
+ 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)
+ 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
+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)
+ {
+ 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)*/
+ break;
+ default :
+ break;
-+ }
-+
++ }
++
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
+ }
+
+ /*saving configuration*/
-+ Devices[stmpeId].Interrupt.ControlReg = tempBuffer[1];
-+
++ Devices[stmpeId].Interrupt.ControlReg = tempBuffer[1];
++
+ /*all interrupt disabled exept gpio */
+ tempBuffer[2] = 0x01;
+ tempBuffer[3] = 0x00;
-+
++
+ /*saving configuration*/
+ /*gpio global interrupt source enabled by default,
+ gpio single source are disabled in "GpioMaskReg"
+ */
+
-+ Devices[stmpeId].Interrupt.EnableReg = 0x0100;
-+
++ Devices[stmpeId].Interrupt.EnableReg = 0x0100;
++
+ /*clear all interrupt flag*/
+ tempBuffer[4] = 0x01; /*ISR_Msb_Index*/
+ tempBuffer[5] = 0xFF; /*ISR_Lsb_Index*/
-+
++
+ /*all gpio interrupt disabled*/
+ tempBuffer[6] = 0x00; /*IEGPIOR_Msb_Index*/
+ tempBuffer[7] = 0x00; /*IEGPIOR_Csb_Index*/
+ tempBuffer[8] = 0x00; /*IEGPIOR_Lsb_Index*/
+ /*saving configuration*/
+ Devices[stmpeId].Interrupt.GpioMaskReg = 0;
-+
++
+ /*clear all gpio interrupt fl/seag*/
+ tempBuffer[9] = 0xFF; /*IEGPIOR_Msb_Index*/
+ tempBuffer[10] = 0xFF; /*IEGPIOR_Csb_Index*/
+ tempBuffer[11] = 0xFF; /*IEGPIOR_Lsb_Index*/
-+
++
+ retval = STMPE2401_Write( stmpeId,tempBuffer, 12 );
-+
++
+ for(i=0;i<MAX_STMPE2401_CALLBACK;i++)
+ {
+ Devices[stmpeId].Interrupt.Callback[i] = &EmptyCallback;
-+ Devices[stmpeId].Interrupt.CallbackParam[i] = NULL;
++ Devices[stmpeId].Interrupt.CallbackParam[i] = NULL;
+ }
-+
++
+ CallbackInstallationCheck[stmpeId] = 0; /*no callback installed*/
-+
++
+ /*saving configuration*/
+ Devices[stmpeId].Interrupt.NdkPin = NdkPin;
+ Devices[stmpeId].Interrupt.NdkPinConfig = NdkPinConfig;
-+
++
+ /*apply configuration*/
+ if(nomadik_gpio_setpinconfig(NdkPin,&NdkPinConfig) != GPIO_OK)
+ {
+ err = request_irq(IRQNO_GPIO(NdkPin), stmp_intr_handler , SA_TRIGGER_FALLING, "stmpe0", NULL);
+ else
+ err = request_irq(IRQNO_GPIO(NdkPin), stmp_intr_handler , SA_TRIGGER_FALLING, "stmpe1", NULL);
-+
++
+ if(err) {
+ printk("unable to Request for the irq %d\n", NdkPin);
+ return err;
+ }
-+ /*Enable the global stmpe interrupt*/
-+ retval = STMPE2401_InterruptAbilitation(stmpeId, STMPE2401_ENABLE_INTERRUPT );
++ /*Enable the global stmpe interrupt*/
++ retval = STMPE2401_InterruptAbilitation(stmpeId, STMPE2401_ENABLE_INTERRUPT );
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
+ This function init Keypad functions
+ Parameter
+ stmpeId = index of the device (0-3)
-+ Settings = keypad settings, Settings.scan field can be ignored for this
++ Settings = keypad settings, Settings.scan field can be ignored for this
+ function, after initializzation is always STMPE2401_SCAN_OFF
-+*/
++*/
+t_STMPE2401_error STMPE2401_Keypad_init(uint8 stmpeId, t_STMPE2401_key_config Settings)
+{
+ t_STMPE2401_error retval = STMPE2401_OK;
+ uint8 tempBuffer[10];
+ uint8 i;
-+
++
+ retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
+ }
-+
++
+ /*settings verification*/
+ if(Settings.columns > 0x00FF)
+ {
+ {
+ retval = STMPE2401_BAD_PARAMETER;
+ }
-+
++
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
+ }
-+
++
+ /*setting GPIO alternate function
+ columns 0-7 are connected to gpio 0-7*/
-+ for(i=0; i<8; i++ )
++ for(i=0; i<8; i++ )
+ {
+ if((Settings.columns & (1<<i)) != 0)
+ {
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
-+ }
++ }
+ /*enable pull-up and disable pull-down*/
+ retval = STMPE2401_SetGpioPull( stmpeId,i, STMPE2401_PULL_UP );
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
-+ }
++ }
+ }
+ }
+ /*row 0-6 are connected to gpio 8-14*/
-+ for(i=0; i<=6; i++ )
++ for(i=0; i<=6; i++ )
+ {
+ if((Settings.rows & (1<<i)) != 0)
+ {
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
-+ }
++ }
+ }
-+ }
++ }
+ /*row 7-11 are connected to gpio 16-20*/
-+ for(i=7; i<=11; i++ )
++ for(i=7; i<=11; i++ )
+ {
+ if((Settings.rows & (1<<i)) != 0)
+ {
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
-+ }
++ }
+ }
-+ }
++ }
+ Settings.scan = STMPE2401_SCAN_OFF;
+ /*save settings*/
+ memcpy(&Devices[stmpeId].Key, &Settings, sizeof(t_STMPE2401_key_config));
+ Parameter
+ stmpeId = index of the device (0-3)
+ status = STMPE2401_SCAN_ON or STMPE2401_SCAN_OFF
-+*/
++*/
+t_STMPE2401_error STMPE2401_Keypad_scan(uint8 stmpeId, uint8 status)
+{
+ t_STMPE2401_error retval = STMPE2401_OK;
+ uint8 tempByte;
-+
++
+ retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
+ if(retval != STMPE2401_OK)
+ {
+ return retval;
+ }
+ tempByte = (Devices[stmpeId].Key.debounce << 1);
-+
++
+ switch(status)
+ {
+ case STMPE2401_SCAN_ON:
+ retval = STMPE2401_BAD_PARAMETER;
+ break;
+ }
-+
++
+ if(retval == STMPE2401_OK)
+ {
+ retval = STMPE2401_WriteByte(stmpeId,KPC_CTRL_Lsb_Index, tempByte );
+ Parameter
+ stmpeId = index of the device (0-3)
+ keys = keys pressed
-+*/
++*/
+t_STMPE2401_error STMPE2401_Keypressed(uint8 stmpeId, t_STMPE2401_key_status *keys)
+{
+ t_STMPE2401_error retval = STMPE2401_OK;
+
+ keys->buttonPressed = 0;
+ keys->buttonReleased = 0;
-+
++
+ retval = STMPE2401_Read( stmpeId,KPC_DATA_BYTE0_Index,tempBuffer, 1 );
+ retval = STMPE2401_Read( stmpeId,KPC_DATA_BYTE1_Index,&tempBuffer[1], 1 );
-+
++
+ if((tempBuffer[0] & STMPE2401_MASK_NO_KEY) != STMPE2401_MASK_NO_KEY )
+ {
+ if((tempBuffer[0] & 0x80) == 0)
+ else
+ {
+ keys->released[0] = tempBuffer[0] & 0x7F;
-+ keys->buttonReleased++;
++ keys->buttonReleased++;
+ }
+ }
+ if((tempBuffer[1] & STMPE2401_MASK_NO_KEY) != STMPE2401_MASK_NO_KEY )
+ 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)
+ retval = STMPE2401_FEAT_NOT_SUPPORTED;
+ break;
+ default :
-+
++
+ break;
+ }
+ Devices[stmpeId].Interrupt.Callback[HwSource] = Callback;
+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*/
+ }
+ 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 )
+ 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:
+ break;
+ }
+ if(retval != STMPE2401_OK)
-+ {
++ {
+ return retval;
+ }
-+
++
+ tempWord = Devices[stmpeId].Interrupt.EnableReg;
+ tempLong = Devices[stmpeId].Interrupt.GpioMaskReg;
-+
++
+ switch(Abilitation)
+ {
+ case STMPE2401_ENABLE_INTERRUPT:
+ }
+ break;
+ case STMPE2401_DISABLE_INTERRUPT:
-+
++
+ if(HwSource <= STMPE2401_GPIO_IRQ(23))
+ {
+ tempLong &=~ ((uint32)1 << HwSource);
+ 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);
+ }
+ }
+ if(retval == STMPE2401_OK)
-+ {
++ {
+ Devices[stmpeId].Interrupt.EnableReg = tempWord;
+ Devices[stmpeId].Interrupt.GpioMaskReg = tempLong;
-+
++
+ if(Abilitation == STMPE2401_ENABLE_INTERRUPT)
+ {
+ InterruptActive[stmpeId] |= ((uint32)1 << HwSource);
+ }
+ }
+ return retval;
-+
++
+}
+
+/* Modified version : enables/disables only global interrupt inside the STMPE2401*/
+
+ 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 )
+ {
+ /*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 :
+ 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)
+ {
+ return err;
+}
+
-+/*IRQ function.
++/*IRQ function.
+*/
+static void nomadik_stmpe0_wq(void * data)
+{
+ 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 );
+ err = STMPE2401_Write( stmpeId, tempBuffer, 4 );
+ }
+ }
-+ }
++ }
+ }
+ if(err == STMPE2401_OK)
-+ {
++ {
+ while(irqSource != 0)
+ {
+ ISx = 8;
+ }
+ /*clear gpio request bit*/
+ irqGpioSource &=~ ((uint32)1 << ISGx);
-+ vector = ISGx;
++ vector = ISGx;
+ if(irqGpioSource == 0)
+ {
+ /*no other gpio request, clear request bit*/
+ {
+ err = STMPE2401_INTERNAL_ERROR;
+ }
-+
++
+ if(err == STMPE2401_OK)
+ {
+ /*Callback execution*/
+ 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 );
+ irqSource = irqSource << 8;
+ irqSource |= tempBuffer[2];
+ irqSource &= 0x1FF; /*remove non ISx bits*/
-+
++
+ if(irqSource == 0)
+ {
+ /*error, no STMPE2401 irq request find !!!*/
+ /*write back flags for interrupt request clearing*/
+ tempBuffer[0] = ISR_Msb_Index;
+ err = STMPE2401_Write( stmpeId,tempBuffer, 3 );
-+
-+
++
++
+ if(irqSource & 0x100)
+ {
+ /*irqGpioSource*/
+ {
+ irqGpioSource = (tempBuffer[1] << 16) | (tempBuffer[2] << 8) | (tempBuffer[3]);
+ }
-+
++
+ if(irqGpioSource == 0)
+ {
+ /*error, no STMPE2401 gpio irq request find !!!*/
+ }
+
+ }
-+ }
++ }
+ }
+ if(err == STMPE2401_OK)
-+ {
++ {
+ while(irqSource != 0)
+ {
+ ISx = 8;
+ {
+ if((irqSource & shift) != 0)
+ {
-+
++
+ break;
+ }
+ ISx --;
+ }
+ if(ISx == 8)
+ {
-+
++
+ for(ISGx=0;ISGx<24;ISGx ++ )
+ {
+ if(irqGpioSource & ((uint32)1 << ISGx ))
+ }
+ /*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)
+ {
+ {
+ err = STMPE2401_INTERNAL_ERROR;
+ }
-+
++
+ if(err == STMPE2401_OK)
+ {
+ /*Callback execution*/
+
+ 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)
+ if(PinIndex >= MAX_STMPE2401_GPIO)
+ {
+ /*number of pin exceeded*/
-+ return STMPE2401_BAD_PARAMETER;
++ return STMPE2401_BAD_PARAMETER;
+ }
+ return STMPE2401_OK;
+}
+ 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;
+
+/*
+ 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)
+ 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;
+ }
+
+/*
+ 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)
+*/
+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;
+}
+
+{
+ 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);
+ 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)
+{
+ 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
+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);
+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:
+#include <asm/arch/debug.h>
+#include <asm/arch/gpio.h>
+
-+#define SIF_SDA GPIO_PIN_4
++#define SIF_SDA GPIO_PIN_4
+#define SIF_SCL GPIO_PIN_5
+#define SIF_SCEN GPIO_PIN_6
+
+#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*/
+ }
+ //GPIO_SetGpioPin(scl);
+ sif_wait150ns(); // hold time
-+
++
+ nomadik_gpio_writepin(SIF_SCL,0,"sif");
+ //GPIO_ClearGpioPin(scl);
+}
+ unsigned char bit=0;
+
+ *p_databyte = 0x0;
-+/*
++/*
+ gpio_config.dev_name = "sif";
+ gpio_config.mode = GPIO_MODE_SOFTWARE;
+ gpio_config.direction = GPIO_DIR_OUTPUT;
+ if (ret) {
+ printk("Error in setting GPIO_PIN_04");
+ }
-+*/
++*/
+ sif_wait150ns();
+ // start
+ //GPIO_ClearGpioPin(scen);
+ // Read bit
+ sif_write_databit(1);
+
-+
++
+ nomadik_gpio_resetpinconfig(SIF_SDA, "sif");
+
+ // turn-round cycle
+{
+ int ret;
+ gpio_config sif_pin;
-+
++
+ sif_pin.dev_name = "sif";
+ sif_pin.mode = GPIO_MODE_SOFTWARE;
+ 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("7)Error in setting GPIO_PIN_04");
+
+ //udelay(100);
+ sif_wait150ns();
-+
++
+ ret = nomadik_gpio_writepin(SIF_SCEN,1,"sif");
+ if (ret) {
+ printk("8)Error in setting GPIO_PIN_06");
+ 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)
+ return -EFAULT;
+
+ switch (cmd) {
-+
++
+ case SIF_READ_CHIP_ID_REV:
+ //copy_from_user(&bklight ,argp, sizeof(int));
+ //sif_read(SIF_CHIPID_VER,&byte_val);
+ 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);
+ 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);
+ sif_write(SIF_GAMMA248, gamma.gamma248);
+ sif_write(SIF_GAMMA256, gamma.gamma256);
+ }
-+ break;
++ break;
+ default:
+ return -EINVAL;
+ }
+/**
+ * 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.
+ */
+
+/**
+ * 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.
+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";
+ 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");
+ 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) {
+ 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);
+ 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;
+}
+
+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.
+ Depends on Nomadik DMA driver.
+
+ If unsure, say N.
-+ choice
++ choice
+ prompt "Driver mode"
+ depends on MMC_NOMADIK
+ default NOMADIK_MMC_DMA
+ config NOMADIK_MMC_DMA
+ depends on MMC_NOMADIK
+ bool "DMA mode"
-+
++
+ config NOMADIK_MMC_POLL
+ depends on MMC_NOMADIK
+ bool "Polling mode"
+ 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
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
+ 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)
+
+
+
-+//--- 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;
+ 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 )
+ /*
+ * Card detection interrupt request
+ */
-+// --- Addition Starts AK
++// --- Addition Starts AK
+ err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_2, 0);
+ if (err != STMPE2401_OK)
+ {
+ }
+ //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");
+ 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);
+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.
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
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
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
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
+ *
+ * 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.
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("ST Microelectronics (prafulla.wadaskar@st.com)");
+MODULE_DESCRIPTION("MTD map driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/drivers/mtd/nand/Kconfig ../new/linux-2.6.20/drivers/mtd/nand/Kconfig
---- linux-2.6.20/drivers/mtd/nand/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/nand/Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -13,6 +13,12 @@ config MTD_NAND
+--- linux-2.6.20.orig/drivers/mtd/nand/Kconfig
++++ linux-2.6.20/drivers/mtd/nand/Kconfig
+@@ -11,10 +11,16 @@ config MTD_NAND
+ help
+ This enables support for accessing all type of NAND flash
devices. For further information see
<http://www.linux-mtd.infradead.org/doc/nand.html>.
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
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
+ 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;
+}
+
+/**
-+ * 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
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
+MODULE_DESCRIPTION("NAND driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/drivers/mtd/onenand/generic.c
---- linux-2.6.20/drivers/mtd/onenand/generic.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/generic.c 2008-09-17 13:23:33.000000000 +0530
-@@ -19,6 +19,7 @@
+--- linux-2.6.20.orig/drivers/mtd/onenand/Kconfig
++++ linux-2.6.20/drivers/mtd/onenand/Kconfig
+@@ -1,39 +1,35 @@
+ #
+ # linux/drivers/mtd/onenand/Kconfig
+ #
+
+-menu "OneNAND Flash Device Drivers"
+- depends on MTD != n
+-
+-config MTD_ONENAND
++menuconfig MTD_ONENAND
+ tristate "OneNAND Device Support"
+ depends on MTD
+ help
+ This enables support for accessing all type of OneNAND flash
+ devices. For further information see
+- <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
++ <http://www.samsung.com/Products/Semiconductor/OneNAND/index.htm>
+
++if MTD_ONENAND
+ config MTD_ONENAND_VERIFY_WRITE
+ bool "Verify OneNAND page writes"
+- depends on MTD_ONENAND
+ help
+ This adds an extra check when data is written to the flash. The
+ OneNAND flash device internally checks only bits transitioning
+ from 1 to 0. There is a rare possibility that even though the
+ device thinks the write was successful, a bit could have been
+ flipped accidentally due to device wear or something else.
+
+ config MTD_ONENAND_GENERIC
+ tristate "OneNAND Flash device via platform device driver"
+- depends on MTD_ONENAND && ARM
++ depends on ARM
+ help
+ Support for OneNAND flash via platform device driver.
+
+ config MTD_ONENAND_OTP
+ bool "OneNAND OTP Support"
+- depends on MTD_ONENAND
+ help
+ One Block of the NAND Flash Array memory is reserved as
+ a One-Time Programmable Block memory area.
+ Also, 1st Block of NAND Flash Array can be used as OTP.
+
+@@ -41,6 +37,30 @@ config MTD_ONENAND_OTP
+ operations as any other NAND Flash Array memory block.
+ OTP block cannot be erased.
+
+ OTP block is fully-guaranteed to be a valid block.
+
+-endmenu
++config MTD_ONENAND_2X_PROGRAM
++ bool "OneNAND 2X program support"
++ help
++ The 2X Program is an extension of Program Operation.
++ Since the device is equipped with two DataRAMs, and two-plane NAND
++ Flash memory array, these two component enables simultaneous program
++ of 4KiB. Plane1 has only even blocks such as block0, block2, block4
++ while Plane2 has only odd blocks such as block1, block3, block5.
++ So MTD regards it as 4KiB page size and 256KiB block size
++
++ Now the following chips support it. (KFXXX16Q2M)
++ Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
++ Mux: KFM2G16Q2M, KFN4G16Q2M,
++
++ And more recent chips
++
++config MTD_ONENAND_SIM
++ tristate "OneNAND simulator support"
++ depends on MTD_PARTITIONS
++ help
++ The simulator may simulate various OneNAND flash chips for the
++ OneNAND MTD layer.
++
++endif # MTD_ONENAND
++
+--- linux-2.6.20.orig/drivers/mtd/onenand/Makefile
++++ linux-2.6.20/drivers/mtd/onenand/Makefile
+@@ -6,6 +6,9 @@
+ obj-$(CONFIG_MTD_ONENAND) += onenand.o
+
+ # Board specific.
+ obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
+
++# Simulator
++obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
++
+ onenand-objs = onenand_base.o onenand_bbt.o
+--- linux-2.6.20.orig/drivers/mtd/onenand/generic.c
++++ linux-2.6.20/drivers/mtd/onenand/generic.c
+@@ -17,10 +17,11 @@
+ #include <linux/slab.h>
+ #include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/mach/flash.h>
-@@ -36,20 +37,30 @@ struct onenand_info {
+
+ #define DRIVER_NAME "onenand"
+@@ -34,24 +35,34 @@ struct onenand_info {
+ struct mtd_info mtd;
+ struct mtd_partition *parts;
struct onenand_chip onenand;
};
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;
}
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);
}
+#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,
}
module_init(generic_onenand_init);
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/Kconfig ../new/linux-2.6.20/drivers/mtd/onenand/Kconfig
---- linux-2.6.20/drivers/mtd/onenand/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/Kconfig 2008-11-19 16:47:03.000000000 +0530
-@@ -2,20 +2,17 @@
- # linux/drivers/mtd/onenand/Kconfig
- #
+ module_exit(generic_onenand_exit);
--menu "OneNAND Flash Device Drivers"
-- depends on MTD != n
--
--config MTD_ONENAND
-+menuconfig MTD_ONENAND
- tristate "OneNAND Device Support"
- depends on MTD
- help
- This enables support for accessing all type of OneNAND flash
- devices. For further information see
-- <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
-+ <http://www.samsung.com/Products/Semiconductor/OneNAND/index.htm>
-
-+if MTD_ONENAND
- config MTD_ONENAND_VERIFY_WRITE
- bool "Verify OneNAND page writes"
-- depends on MTD_ONENAND
- help
- This adds an extra check when data is written to the flash. The
- OneNAND flash device internally checks only bits transitioning
-@@ -25,13 +22,12 @@ config MTD_ONENAND_VERIFY_WRITE
-
- config MTD_ONENAND_GENERIC
- tristate "OneNAND Flash device via platform device driver"
-- depends on MTD_ONENAND && ARM
-+ depends on ARM
- help
- Support for OneNAND flash via platform device driver.
-
- config MTD_ONENAND_OTP
- bool "OneNAND OTP Support"
-- depends on MTD_ONENAND
- help
- One Block of the NAND Flash Array memory is reserved as
- a One-Time Programmable Block memory area.
-@@ -43,4 +39,28 @@ config MTD_ONENAND_OTP
-
- OTP block is fully-guaranteed to be a valid block.
-
--endmenu
-+config MTD_ONENAND_2X_PROGRAM
-+ bool "OneNAND 2X program support"
-+ help
-+ The 2X Program is an extension of Program Operation.
-+ Since the device is equipped with two DataRAMs, and two-plane NAND
-+ Flash memory array, these two component enables simultaneous program
-+ of 4KiB. Plane1 has only even blocks such as block0, block2, block4
-+ while Plane2 has only odd blocks such as block1, block3, block5.
-+ So MTD regards it as 4KiB page size and 256KiB block size
-+
-+ Now the following chips support it. (KFXXX16Q2M)
-+ Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
-+ Mux: KFM2G16Q2M, KFN4G16Q2M,
-+
-+ And more recent chips
-+
-+config MTD_ONENAND_SIM
-+ tristate "OneNAND simulator support"
-+ depends on MTD_PARTITIONS
-+ help
-+ The simulator may simulate various OneNAND flash chips for the
-+ OneNAND MTD layer.
-+
-+endif # MTD_ONENAND
-+
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/Makefile ../new/linux-2.6.20/drivers/mtd/onenand/Makefile
---- linux-2.6.20/drivers/mtd/onenand/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/Makefile 2008-11-19 16:47:03.000000000 +0530
-@@ -8,4 +8,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
- # Board specific.
- obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
-
-+# Simulator
-+obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
-+
- onenand-objs = onenand_base.o onenand_bbt.o
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_base.c
---- linux-2.6.20/drivers/mtd/onenand/onenand_base.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_base.c 2008-11-19 16:47:03.000000000 +0530
-@@ -33,8 +33,8 @@ static struct nand_ecclayout onenand_oob
+--- linux-2.6.20.orig/drivers/mtd/onenand/onenand_base.c
++++ linux-2.6.20/drivers/mtd/onenand/onenand_base.c
+@@ -31,12 +31,12 @@ static struct nand_ecclayout onenand_oob
+ 24, 25, 26, 27, 28,
+ 40, 41, 42, 43, 44,
56, 57, 58, 59, 60,
},
.oobfree = {
}
};
-@@ -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 */
};
/**
* 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)
{
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)
{
-
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);
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);
/* 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:
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) {
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)
{
/* 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)) {
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;
/* 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);
}
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;
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);
}
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;
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);
}
* 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;
}
/**
-@@ -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
*/
}
/**
-@@ -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);
}
/**
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)) {
+ 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;
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);
}
}
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;
}
}
+ 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)) {
+ *
+ * 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;
+ 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 */
}
#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
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;
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);
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);
+
+ return ret;
+}
-+
+
+- *retlen = written;
+/**
+ * onenand_write - [MTD Interface] write buffer to FLASH
+ * @param mtd MTD device structure
+ };
+ 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;
}
{
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))) {
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 */
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);
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;
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)
{
}
/**
-@@ -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};
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);
}
/**
-@@ -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;
}
}
/**
-@@ -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
*
* 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)
{
}
/**
-@@ -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)
{
}
/**
-@@ -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) {
/* 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 */
}
onenand_check_lock_status(this);
-@@ -1519,7 +2002,7 @@ static int onenand_unlock_all(struct mtd
+
return 0;
}
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;
/* 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
/* 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);
/* 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;
/* 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;
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;
}
/**
-@@ -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 */
/**
{
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 */
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);
}
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:
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);
/* 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 */
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)
{
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))
/* 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) {
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;
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 */
}
EXPORT_SYMBOL_GPL(onenand_scan);
-@@ -2157,3 +2727,4 @@ EXPORT_SYMBOL_GPL(onenand_release);
+ EXPORT_SYMBOL_GPL(onenand_release);
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
MODULE_DESCRIPTION("Generic OneNAND flash driver code");
+
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c
---- linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c 2008-09-17 13:23:33.000000000 +0530
-@@ -10,6 +10,11 @@
+--- linux-2.6.20.orig/drivers/mtd/onenand/onenand_bbt.c
++++ linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c
+@@ -8,19 +8,24 @@
+ *
+ * Derived from nand_bbt.c
*
* TODO:
* Split BBT core and chip specific BBT.
*/
#include <linux/slab.h>
-@@ -17,8 +22,8 @@
+ #include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/compatmac.h>
/**
* 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;
/* 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;
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.
*
*/
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
+ * published by the Free Software Foundation.
+ */
+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/vmalloc.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/onenand.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/vmalloc.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/onenand.h>
++
++#include <linux/io.h>
++
++#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
++#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
++#endif
++#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
++#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
++#endif
++#ifndef CONFIG_ONENAND_SIM_VERSION_ID
++#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
++#endif
++
++static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER;
++static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID;
++static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
++
++struct onenand_flash {
++ void __iomem *base;
++ void __iomem *data;
++};
++
++#define ONENAND_CORE(flash) (flash->data)
++#define ONENAND_CORE_SPARE(flash, this, offset) \
++ ((flash->data) + (this->chipsize) + (offset >> 5))
++
++#define ONENAND_MAIN_AREA(this, offset) \
++ (this->base + ONENAND_DATARAM + offset)
++
++#define ONENAND_SPARE_AREA(this, offset) \
++ (this->base + ONENAND_SPARERAM + offset)
++
++#define ONENAND_GET_WP_STATUS(this) \
++ (readw(this->base + ONENAND_REG_WP_STATUS))
++
++#define ONENAND_SET_WP_STATUS(v, this) \
++ (writew(v, this->base + ONENAND_REG_WP_STATUS))
++
++/* It has all 0xff chars */
++#define MAX_ONENAND_PAGESIZE (2048 + 64)
++static unsigned char *ffchars;
++
++static struct mtd_partition os_partitions[] = {
++ {
++ .name = "OneNAND simulator partition",
++ .offset = 0,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++/*
++ * OneNAND simulator mtd
++ */
++struct onenand_info {
++ struct mtd_info mtd;
++ struct mtd_partition *parts;
++ struct onenand_chip onenand;
++ struct onenand_flash flash;
++};
++
++static struct onenand_info *info;
++
++#define DPRINTK(format, args...) \
++do { \
++ printk(KERN_DEBUG "%s[%d]: " format "\n", __func__, \
++ __LINE__, ##args); \
++} while (0)
++
++/**
++ * onenand_lock_handle - Handle Lock scheme
++ * @this: OneNAND device structure
++ * @cmd: The command to be sent
++ *
++ * Send lock command to OneNAND device.
++ * The lock scheme depends on chip type.
++ */
++static void onenand_lock_handle(struct onenand_chip *this, int cmd)
++{
++ int block_lock_scheme;
++ int status;
++
++ status = ONENAND_GET_WP_STATUS(this);
++ block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
++
++ switch (cmd) {
++ case ONENAND_CMD_UNLOCK:
++ if (block_lock_scheme)
++ ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
++ else
++ ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
++ break;
++
++ case ONENAND_CMD_LOCK:
++ if (block_lock_scheme)
++ ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
++ else
++ ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
++ break;
++
++ case ONENAND_CMD_LOCK_TIGHT:
++ if (block_lock_scheme)
++ ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
++ else
++ ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
++ break;
++
++ default:
++ break;
++ }
++}
++
++/**
++ * onenand_bootram_handle - Handle BootRAM area
++ * @this: OneNAND device structure
++ * @cmd: The command to be sent
++ *
++ * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
++ */
++static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
++{
++ switch (cmd) {
++ case ONENAND_CMD_READID:
++ writew(manuf_id, this->base);
++ writew(device_id, this->base + 2);
++ writew(version_id, this->base + 4);
++ break;
++
++ default:
++ /* REVIST: Handle other commands */
++ break;
++ }
++}
++
++/**
++ * onenand_update_interrupt - Set interrupt register
++ * @this: OneNAND device structure
++ * @cmd: The command to be sent
++ *
++ * Update interrupt register. The status depends on command.
++ */
++static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
++{
++ int interrupt = ONENAND_INT_MASTER;
++
++ switch (cmd) {
++ case ONENAND_CMD_READ:
++ case ONENAND_CMD_READOOB:
++ interrupt |= ONENAND_INT_READ;
++ break;
++
++ case ONENAND_CMD_PROG:
++ case ONENAND_CMD_PROGOOB:
++ interrupt |= ONENAND_INT_WRITE;
++ break;
++
++ case ONENAND_CMD_ERASE:
++ interrupt |= ONENAND_INT_ERASE;
++ break;
++
++ case ONENAND_CMD_RESET:
++ interrupt |= ONENAND_INT_RESET;
++ break;
++
++ default:
++ break;
++ }
++
++ writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
++}
++
++/**
++ * onenand_check_overwrite - Check if over-write happened
++ * @dest: The destination pointer
++ * @src: The source pointer
++ * @count: The length to be check
++ *
++ * Returns: 0 on same, otherwise 1
++ *
++ * Compare the source with destination
++ */
++static int onenand_check_overwrite(void *dest, void *src, size_t count)
++{
++ unsigned int *s = (unsigned int *) src;
++ unsigned int *d = (unsigned int *) dest;
++ int i;
++
++ count >>= 2;
++ for (i = 0; i < count; i++)
++ if ((*s++ ^ *d++) != 0)
++ return 1;
++
++ return 0;
++}
++
++/**
++ * onenand_data_handle - Handle OneNAND Core and DataRAM
++ * @this: OneNAND device structure
++ * @cmd: The command to be sent
++ * @dataram: Which dataram used
++ * @offset: The offset to OneNAND Core
++ *
++ * Copy data from OneNAND Core to DataRAM (read)
++ * Copy data from DataRAM to OneNAND Core (write)
++ * Erase the OneNAND Core (erase)
++ */
++static void onenand_data_handle(struct onenand_chip *this, int cmd,
++ int dataram, unsigned int offset)
++{
++ struct mtd_info *mtd = &info->mtd;
++ struct onenand_flash *flash = this->priv;
++ int main_offset, spare_offset;
++ void __iomem *src;
++ void __iomem *dest;
++ unsigned int i;
++
++ if (dataram) {
++ main_offset = mtd->writesize;
++ spare_offset = mtd->oobsize;
++ } else {
++ main_offset = 0;
++ spare_offset = 0;
++ }
++
++ switch (cmd) {
++ case ONENAND_CMD_READ:
++ src = ONENAND_CORE(flash) + offset;
++ dest = ONENAND_MAIN_AREA(this, main_offset);
++ memcpy(dest, src, mtd->writesize);
++ /* Fall through */
++
++ case ONENAND_CMD_READOOB:
++ src = ONENAND_CORE_SPARE(flash, this, offset);
++ dest = ONENAND_SPARE_AREA(this, spare_offset);
++ memcpy(dest, src, mtd->oobsize);
++ break;
++
++ case ONENAND_CMD_PROG:
++ src = ONENAND_MAIN_AREA(this, main_offset);
++ dest = ONENAND_CORE(flash) + offset;
++ /* To handle partial write */
++ for (i = 0; i < (1 << mtd->subpage_sft); i++) {
++ int off = i * this->subpagesize;
++ if (!memcmp(src + off, ffchars, this->subpagesize))
++ continue;
++ if (memcmp(dest + off, ffchars, this->subpagesize) &&
++ onenand_check_overwrite(dest + off, src + off, this->subpagesize))
++ printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
++ memcpy(dest + off, src + off, this->subpagesize);
++ }
++ /* Fall through */
++
++ case ONENAND_CMD_PROGOOB:
++ src = ONENAND_SPARE_AREA(this, spare_offset);
++ /* Check all data is 0xff chars */
++ if (!memcmp(src, ffchars, mtd->oobsize))
++ break;
++
++ dest = ONENAND_CORE_SPARE(flash, this, offset);
++ if (memcmp(dest, ffchars, mtd->oobsize) &&
++ onenand_check_overwrite(dest, src, mtd->oobsize))
++ printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
++ offset);
++ memcpy(dest, src, mtd->oobsize);
++ break;
++
++ case ONENAND_CMD_ERASE:
++ memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
++ memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
++ (mtd->erasesize >> 5));
++ break;
++
++ default:
++ break;
++ }
++}
++
++/**
++ * onenand_command_handle - Handle command
++ * @this: OneNAND device structure
++ * @cmd: The command to be sent
++ *
++ * Emulate OneNAND command.
++ */
++static void onenand_command_handle(struct onenand_chip *this, int cmd)
++{
++ unsigned long offset = 0;
++ int block = -1, page = -1, bufferram = -1;
++ int dataram = 0;
++
++ switch (cmd) {
++ case ONENAND_CMD_UNLOCK:
++ case ONENAND_CMD_LOCK:
++ case ONENAND_CMD_LOCK_TIGHT:
++ case ONENAND_CMD_UNLOCK_ALL:
++ onenand_lock_handle(this, cmd);
++ break;
++
++ case ONENAND_CMD_BUFFERRAM:
++ /* Do nothing */
++ return;
++
++ default:
++ block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
++ if (block & (1 << ONENAND_DDP_SHIFT)) {
++ block &= ~(1 << ONENAND_DDP_SHIFT);
++ /* The half of chip block */
++ block += this->chipsize >> (this->erase_shift + 1);
++ }
++ if (cmd == ONENAND_CMD_ERASE)
++ break;
++
++ page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
++ page = (page >> ONENAND_FPA_SHIFT);
++ bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
++ bufferram >>= ONENAND_BSA_SHIFT;
++ bufferram &= ONENAND_BSA_DATARAM1;
++ dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
++ break;
++ }
++
++ if (block != -1)
++ offset += block << this->erase_shift;
++
++ if (page != -1)
++ offset += page << this->page_shift;
++
++ onenand_data_handle(this, cmd, dataram, offset);
++
++ onenand_update_interrupt(this, cmd);
++}
++
++/**
++ * onenand_writew - [OneNAND Interface] Emulate write operation
++ * @value: value to write
++ * @addr: address to write
++ *
++ * Write OneNAND register with value
++ */
++static void onenand_writew(unsigned short value, void __iomem * addr)
++{
++ struct onenand_chip *this = info->mtd.priv;
++
++ /* BootRAM handling */
++ if (addr < this->base + ONENAND_DATARAM) {
++ onenand_bootram_handle(this, value);
++ return;
++ }
++ /* Command handling */
++ if (addr == this->base + ONENAND_REG_COMMAND)
++ onenand_command_handle(this, value);
++
++ writew(value, addr);
++}
++
++/**
++ * flash_init - Initialize OneNAND simulator
++ * @flash: OneNAND simulator data strucutres
++ *
++ * Initialize OneNAND simulator.
++ */
++static int __init flash_init(struct onenand_flash *flash)
++{
++ int density, size;
++ int buffer_size;
++
++ flash->base = kzalloc(131072, GFP_KERNEL);
++ if (!flash->base) {
++ printk(KERN_ERR "Unable to allocate base address.\n");
++ return -ENOMEM;
++ }
++
++ density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
++ size = ((16 << 20) << density);
++
++ ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
++ if (!ONENAND_CORE(flash)) {
++ printk(KERN_ERR "Unable to allocate nand core address.\n");
++ kfree(flash->base);
++ return -ENOMEM;
++ }
++
++ memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
++
++ /* Setup registers */
++ writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
++ writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
++ writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
++
++ if (density < 2)
++ buffer_size = 0x0400; /* 1KiB page */
++ else
++ buffer_size = 0x0800; /* 2KiB page */
++ writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
++
++ return 0;
++}
++
++/**
++ * flash_exit - Clean up OneNAND simulator
++ * @flash: OneNAND simulator data structures
++ *
++ * Clean up OneNAND simulator.
++ */
++static void flash_exit(struct onenand_flash *flash)
++{
++ vfree(ONENAND_CORE(flash));
++ kfree(flash->base);
++}
++
++static int __init onenand_sim_init(void)
++{
++ /* Allocate all 0xff chars pointer */
++ ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
++ if (!ffchars) {
++ printk(KERN_ERR "Unable to allocate ff chars.\n");
++ return -ENOMEM;
++ }
++ memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
++
++ /* Allocate OneNAND simulator mtd pointer */
++ info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
++ if (!info) {
++ printk(KERN_ERR "Unable to allocate core structures.\n");
++ kfree(ffchars);
++ return -ENOMEM;
++ }
++
++ /* Override write_word function */
++ info->onenand.write_word = onenand_writew;
++
++ if (flash_init(&info->flash)) {
++ printk(KERN_ERR "Unable to allocate flash.\n");
++ kfree(ffchars);
++ kfree(info);
++ return -ENOMEM;
++ }
++
++ info->parts = os_partitions;
++
++ info->onenand.base = info->flash.base;
++ info->onenand.priv = &info->flash;
++
++ info->mtd.name = "OneNAND simulator";
++ info->mtd.priv = &info->onenand;
++ info->mtd.owner = THIS_MODULE;
++
++ if (onenand_scan(&info->mtd, 1)) {
++ flash_exit(&info->flash);
++ kfree(ffchars);
++ kfree(info);
++ return -ENXIO;
++ }
++
++ add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
++
++ return 0;
++}
++
++static void __exit onenand_sim_exit(void)
++{
++ struct onenand_chip *this = info->mtd.priv;
++ struct onenand_flash *flash = this->priv;
++
++ onenand_release(&info->mtd);
++ flash_exit(flash);
++ kfree(ffchars);
++ kfree(info);
++}
++
++module_init(onenand_sim_init);
++module_exit(onenand_sim_exit);
++
++MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
++MODULE_DESCRIPTION("The OneNAND flash simulator");
++MODULE_LICENSE("GPL");
+--- linux-2.6.20.orig/drivers/net/Makefile
++++ linux-2.6.20/drivers/net/Makefile
+@@ -211,9 +211,10 @@ obj-$(CONFIG_HAMRADIO) += hamradio/
+ obj-$(CONFIG_IRDA) += irda/
+ obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+ obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
+
+ obj-$(CONFIG_NETCONSOLE) += netconsole.o
++obj-$(CONFIG_KGDBOE) += kgdboe.o
+
+ obj-$(CONFIG_FS_ENET) += fs_enet/
+
+ obj-$(CONFIG_NETXEN_NIC) += netxen/
+--- /dev/null
++++ linux-2.6.20/drivers/net/kgdboe.c
+@@ -0,0 +1,294 @@
++/*
++ * drivers/net/kgdboe.c
++ *
++ * A network interface for GDB.
++ * Based upon 'gdbserial' by David Grothe <dave@gcom.com>
++ * and Scott Foehner <sfoehner@engr.sgi.com>
++ *
++ * Maintainers: Amit S. Kale <amitkale@linsyssoft.com> and
++ * Tom Rini <trini@kernel.crashing.org>
++ *
++ * 2004 (c) Amit S. Kale <amitkale@linsyssoft.com>
++ * 2004-2005 (c) MontaVista Software, Inc.
++ * 2005 (c) Wind River Systems, Inc.
++ *
++ * Contributors at various stages not listed above:
++ * San Mehat <nettwerk@biodome.org>, Robert Walsh <rjwalsh@durables.org>,
++ * wangdi <wangdi@clusterfs.com>, Matt Mackall <mpm@selenic.com>,
++ * Pavel Machek <pavel@suse.cz>, Jason Wessel <jason.wessel@windriver.com>
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/string.h>
++#include <linux/kgdb.h>
++#include <linux/netpoll.h>
++#include <linux/init.h>
++
++#include <asm/atomic.h>
++
++#define IN_BUF_SIZE 512 /* power of 2, please */
++#define NOT_CONFIGURED_STRING "not_configured"
++#define OUT_BUF_SIZE 30 /* We don't want to send too big of a packet. */
++#define MAX_KGDBOE_CONFIG_STR 256
++
++static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE];
++static int in_head, in_tail, out_count;
++static atomic_t in_count;
++/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */
++static int configured;
++static struct kgdb_io local_kgdb_io_ops;
++static int use_dynamic_mac;
++
++MODULE_DESCRIPTION("KGDB driver for network interfaces");
++MODULE_LICENSE("GPL");
++static char config[MAX_KGDBOE_CONFIG_STR] = NOT_CONFIGURED_STRING;
++static struct kparam_string kps = {
++ .string = config,
++ .maxlen = MAX_KGDBOE_CONFIG_STR,
++};
++
++static void rx_hook(struct netpoll *np, int port, char *msg, int len,
++ struct sk_buff *skb)
++{
++ int i;
++
++ np->remote_port = port;
++
++ /* Copy the MAC address if we need to. */
++ if (use_dynamic_mac) {
++ memcpy(np->remote_mac, eth_hdr(skb)->h_source,
++ sizeof(np->remote_mac));
++ use_dynamic_mac = 0;
++ }
++
++ /*
++ * This could be GDB trying to attach. But it could also be GDB
++ * finishing up a session, with kgdb_connected=0 but GDB sending
++ * an ACK for the final packet. To make sure we don't try and
++ * make a breakpoint when GDB is leaving, make sure that if
++ * !kgdb_connected the only len == 1 packet we allow is ^C.
++ */
++ if (!kgdb_connected && (len != 1 || msg[0] == 3) &&
++ !atomic_read(&kgdb_setting_breakpoint)) {
++ tasklet_schedule(&kgdb_tasklet_breakpoint);
++ }
++
++ for (i = 0; i < len; i++) {
++ if (msg[i] == 3)
++ tasklet_schedule(&kgdb_tasklet_breakpoint);
++
++ if (atomic_read(&in_count) >= IN_BUF_SIZE) {
++ /* buffer overflow, clear it */
++ in_head = in_tail = 0;
++ atomic_set(&in_count, 0);
++ break;
++ }
++ in_buf[in_head++] = msg[i];
++ in_head &= (IN_BUF_SIZE - 1);
++ atomic_inc(&in_count);
++ }
++}
++
++static struct netpoll np = {
++ .dev_name = "eth0",
++ .name = "kgdboe",
++ .rx_hook = rx_hook,
++ .local_port = 6443,
++ .remote_port = 6442,
++ .remote_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
++};
++
++static void eth_pre_exception_handler(void)
++{
++ /* Increment the module count when the debugger is active */
++ if (!kgdb_connected)
++ try_module_get(THIS_MODULE);
++ netpoll_set_trap(1);
++}
++
++static void eth_post_exception_handler(void)
++{
++ /* decrement the module count when the debugger detaches */
++ if (!kgdb_connected)
++ module_put(THIS_MODULE);
++ netpoll_set_trap(0);
++}
++
++static int eth_get_char(void)
++{
++ int chr;
++
++ while (atomic_read(&in_count) == 0)
++ netpoll_poll(&np);
++
++ chr = in_buf[in_tail++];
++ in_tail &= (IN_BUF_SIZE - 1);
++ atomic_dec(&in_count);
++ return chr;
++}
++
++static void eth_flush_buf(void)
++{
++ if (out_count && np.dev) {
++ netpoll_send_udp(&np, out_buf, out_count);
++ memset(out_buf, 0, sizeof(out_buf));
++ out_count = 0;
++ }
++}
++
++static void eth_put_char(u8 chr)
++{
++ out_buf[out_count++] = chr;
++ if (out_count == OUT_BUF_SIZE)
++ eth_flush_buf();
++}
++
++static int option_setup(char *opt)
++{
++ char opt_scratch[MAX_KGDBOE_CONFIG_STR];
++
++ /* If we're being given a new configuration, copy it in. */
++ if (opt != config)
++ strcpy(config, opt);
++ /* But work on a copy as netpoll_parse_options will eat it. */
++ strcpy(opt_scratch, opt);
++ configured = !netpoll_parse_options(&np, opt_scratch);
++
++ use_dynamic_mac = 1;
++
++ return 0;
++}
++__setup("kgdboe=", option_setup);
++
++/* With our config string set by some means, configure kgdboe. */
++static int configure_kgdboe(void)
++{
++ /* Try out the string. */
++ option_setup(config);
++
++ if (!configured) {
++ printk(KERN_ERR "kgdboe: configuration incorrect - kgdboe not "
++ "loaded.\n");
++ printk(KERN_ERR " Usage: kgdboe=[src-port]@[src-ip]/[dev],"
++ "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
++ return -EINVAL;
++ }
++
++ /* Bring it up. */
++ if (netpoll_setup(&np)) {
++ printk(KERN_ERR "kgdboe: netpoll_setup failed kgdboe failed\n");
++ return -EINVAL;
++ }
++
++ if (kgdb_register_io_module(&local_kgdb_io_ops)) {
++ netpoll_cleanup(&np);
++ return -EINVAL;
++ }
++
++ configured = 2;
++
++ return 0;
++}
++
++static int init_kgdboe(void)
++{
++ int ret;
++
++ /* Already done? */
++ if (configured == 2)
++ return 0;
++
++ /* OK, go ahead and do it. */
++ ret = configure_kgdboe();
++
++ if (configured == 2)
++ printk(KERN_INFO "kgdboe: debugging over ethernet enabled\n");
++
++ return ret;
++}
++
++static void cleanup_kgdboe(void)
++{
++ netpoll_cleanup(&np);
++ configured = 0;
++ kgdb_unregister_io_module(&local_kgdb_io_ops);
++}
++
++static int param_set_kgdboe_var(const char *kmessage, struct kernel_param *kp)
++{
++ char kmessage_save[MAX_KGDBOE_CONFIG_STR];
++ int msg_len = strlen(kmessage);
++
++ if (msg_len + 1 > MAX_KGDBOE_CONFIG_STR) {
++ printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
++ kp->name, MAX_KGDBOE_CONFIG_STR - 1);
++ return -ENOSPC;
++ }
++
++ if (kgdb_connected) {
++ printk(KERN_ERR "kgdboe: Cannot reconfigure while KGDB is "
++ "connected.\n");
++ return 0;
++ }
++
++ /* Start the reconfiguration process by saving the old string */
++ strncpy(kmessage_save, config, sizeof(kmessage_save));
++
++
++ /* Copy in the new param and strip out invalid characters so we
++ * can optionally specify the MAC.
++ */
++ strncpy(config, kmessage, sizeof(config));
++ msg_len--;
++ while (msg_len > 0 &&
++ (config[msg_len] < ',' || config[msg_len] > 'f')) {
++ config[msg_len] = '\0';
++ msg_len--;
++ }
++
++ /* Check to see if we are unconfiguring the io module and that it
++ * was in a fully configured state, as this is the only time that
++ * netpoll_cleanup should get called
++ */
++ if (configured == 2 && strcmp(config, NOT_CONFIGURED_STRING) == 0) {
++ printk(KERN_INFO "kgdboe: reverting to unconfigured state\n");
++ cleanup_kgdboe();
++ return 0;
++ } else
++ /* Go and configure with the new params. */
++ configure_kgdboe();
++
++ if (configured == 2)
++ return 0;
++
++ /* If the new string was invalid, revert to the previous state, which
++ * is at a minimum not_configured. */
++ strncpy(config, kmessage_save, sizeof(config));
++ if (strcmp(kmessage_save, NOT_CONFIGURED_STRING) != 0) {
++ printk(KERN_INFO "kgdboe: reverting to prior configuration\n");
++ /* revert back to the original config */
++ strncpy(config, kmessage_save, sizeof(config));
++ configure_kgdboe();
++ }
++ return 0;
++}
++
++static struct kgdb_io local_kgdb_io_ops = {
++ .read_char = eth_get_char,
++ .write_char = eth_put_char,
++ .init = init_kgdboe,
++ .flush = eth_flush_buf,
++ .pre_exception = eth_pre_exception_handler,
++ .post_exception = eth_post_exception_handler
++};
++
++module_init(init_kgdboe);
++module_exit(cleanup_kgdboe);
++module_param_call(kgdboe, param_set_kgdboe_var, param_get_string, &kps, 0644);
++MODULE_PARM_DESC(kgdboe, " kgdboe=[src-port]@[src-ip]/[dev],"
++ "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
+--- linux-2.6.20.orig/drivers/net/smc91x.c
++++ linux-2.6.20/drivers/net/smc91x.c
+@@ -1,5 +1,6 @@
++
+ /*
+ * smc91x.c
+ * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
+ *
+ * Copyright (C) 1996 by Erik Stahlman
+@@ -63,11 +64,10 @@ static const char version[] =
+ /* Debugging level */
+ #ifndef SMC_DEBUG
+ #define SMC_DEBUG 0
+ #endif
+
+-
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+@@ -88,10 +88,12 @@ static const char version[] =
+
+ #include <asm/io.h>
+
+ #include "smc91x.h"
+
++#include <linux/delay.h>
++
+ #ifdef CONFIG_ISA
+ /*
+ * the LAN91C111 can be at any of the following port addresses. To change,
+ * for a slightly different card, you can add it to the array. Keep in
+ * mind that the array must end in zero.
+@@ -266,11 +268,10 @@ static void PRINT_PKT(u_char *buf, int l
+ }
+ #else
+ #define PRINT_PKT(x...) do { } while(0)
+ #endif
+
+-
+ /* this enables an interrupt in the interrupt mask register */
+ #define SMC_ENABLE_INT(x) do { \
+ unsigned char mask; \
+ spin_lock_irq(&lp->lock); \
+ mask = SMC_GET_INT_MASK(); \
+@@ -306,11 +307,10 @@ static void PRINT_PKT(u_char *buf, int l
+ cpu_relax(); \
+ } \
+ } \
+ } while (0)
+
+-
+ /*
+ * this does a soft reset on the device
+ */
+ static void smc_reset(struct net_device *dev)
+ {
+@@ -492,12 +492,11 @@ static inline void smc_rcv(struct net_d
+
+ /* First two words are status and packet length */
+ SMC_GET_PKT_HDR(status, packet_len);
+ packet_len &= 0x07ff; /* mask off top bits */
+ DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
+- dev->name, packet_number, status,
+- packet_len, packet_len);
++ dev->name, packet_number, status, packet_len, packet_len);
+
+ back:
+ if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
+ if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) {
+ /* accept VLAN packets */
+@@ -833,11 +832,10 @@ static void smc_tx(struct net_device *de
+ SMC_SELECT_BANK(0);
+ SMC_SET_TCR(lp->tcr_cur_mode);
+ SMC_SELECT_BANK(2);
+ }
+
+-
+ /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
+
+ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
+ {
+ struct smc_local *lp = netdev_priv(dev);
+@@ -925,11 +923,13 @@ static void smc_phy_write(struct net_dev
+
+ /* Idle - 32 ones */
+ smc_mii_out(dev, 0xffffffff, 32);
+
+ /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */
+- smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
++ smc_mii_out(dev,
++ 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata,
++ 32);
+
+ /* Return to idle state */
+ SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
+
+ DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+@@ -959,12 +959,11 @@ static void smc_phy_detect(struct net_de
+
+ /* Read the PHY identifiers */
+ id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1);
+ id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2);
+
+- DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n",
+- dev->name, id1, id2);
++ DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", dev->name, id1, id2);
+
+ /* Make sure it is a valid identifier */
+ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
+ id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
+ /* Save the PHY's address */
+@@ -1182,11 +1181,13 @@ static void smc_phy_configure(struct wor
+ if (my_phy_caps & BMSR_10HALF)
+ my_ad_caps |= ADVERTISE_10HALF;
+
+ /* Disable capabilities not selected by our user */
+ if (lp->ctl_rspeed != 100)
+- my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
++ my_ad_caps &=
++ ~(ADVERTISE_100BASE4 | ADVERTISE_100FULL |
++ ADVERTISE_100HALF);
+
+ if (!lp->ctl_rfduplx)
+ my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
+
+ /* Update our Auto-Neg Advertisement Register */
+@@ -1312,15 +1313,16 @@ static irqreturn_t smc_interrupt(int irq
+
+ do {
+ status = SMC_GET_INT();
+
+ DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
+- dev->name, status, mask,
+- ({ int meminfo; SMC_SELECT_BANK(0);
++ dev->name, status, mask, ( {
++ int meminfo;
++ SMC_SELECT_BANK(0);
+ meminfo = SMC_GET_MIR();
+- SMC_SELECT_BANK(2); meminfo; }),
+- SMC_GET_FIFO());
++ SMC_SELECT_BANK(2);
++ meminfo;}), SMC_GET_FIFO());
+
+ status &= mask;
+ if (!status)
+ break;
+
+@@ -1352,14 +1354,22 @@ static irqreturn_t smc_interrupt(int irq
+ card_stats >>= 4;
+
+ /* multiple collisions */
+ lp->stats.collisions += card_stats & 0xF;
+ } else if (status & IM_RX_OVRN_INT) {
+- DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
+- ({ int eph_st; SMC_SELECT_BANK(0);
+- eph_st = SMC_GET_EPH_STATUS();
+- SMC_SELECT_BANK(2); eph_st; }) );
++ DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, ( {
++ int
++ eph_st;
++ SMC_SELECT_BANK
++ (0);
++ eph_st
++ =
++ SMC_GET_EPH_STATUS
++ ();
++ SMC_SELECT_BANK
++ (2);
++ eph_st;}));
+ SMC_ACK_INT(IM_RX_OVRN_INT);
+ lp->stats.rx_errors++;
+ lp->stats.rx_fifo_errors++;
+ } else if (status & IM_EPH_INT) {
+ smc_eph_interrupt(dev);
+@@ -1498,11 +1508,12 @@ static void smc_set_multicast_list(struc
+ else if (dev->mc_count) {
+ int i;
+ struct dev_mc_list *cur_addr;
+
+ /* table for flipping the order of 3 bits */
+- static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7};
++ static const unsigned char invert3[] =
++ { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+ /* start with a table of all zeros: reject all */
+ memset(multicast_table, 0, sizeof(multicast_table));
+
+ cur_addr = dev->mc_list;
+@@ -1551,18 +1562,16 @@ static void smc_set_multicast_list(struc
+ }
+ SMC_SELECT_BANK(2);
+ spin_unlock_irq(&lp->lock);
+ }
+
+-
+ /*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc..
+ */
+-static int
+-smc_open(struct net_device *dev)
++static int smc_open(struct net_device *dev)
+ {
+ struct smc_local *lp = netdev_priv(dev);
+
+ DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+@@ -1657,22 +1666,22 @@ smc_ethtool_getsettings(struct net_devic
+ spin_lock_irq(&lp->lock);
+ ret = mii_ethtool_gset(&lp->mii, cmd);
+ spin_unlock_irq(&lp->lock);
+ } else {
+ cmd->supported = SUPPORTED_10baseT_Half |
+- SUPPORTED_10baseT_Full |
+- SUPPORTED_TP | SUPPORTED_AUI;
++ SUPPORTED_10baseT_Full | SUPPORTED_TP | SUPPORTED_AUI;
+
+ if (lp->ctl_rspeed == 10)
+ cmd->speed = SPEED_10;
+ else if (lp->ctl_rspeed == 100)
+ cmd->speed = SPEED_100;
+
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->port = 0;
+- cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
++ cmd->duplex =
++ lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
+
+ ret = 0;
+ }
+
+ return ret;
+@@ -1689,12 +1698,12 @@ smc_ethtool_setsettings(struct net_devic
+ ret = mii_ethtool_sset(&lp->mii, cmd);
+ spin_unlock_irq(&lp->lock);
+ } else {
+ if (cmd->autoneg != AUTONEG_DISABLE ||
+ cmd->speed != SPEED_10 ||
+- (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
+- (cmd->port != PORT_TP && cmd->port != PORT_AUI))
++ (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
++ || (cmd->port != PORT_TP && cmd->port != PORT_AUI))
+ return -EINVAL;
+
+ // lp->port = cmd->port;
+ lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL;
+
+@@ -1710,11 +1719,12 @@ smc_ethtool_setsettings(struct net_devic
+ static void
+ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+ {
+ strncpy(info->driver, CARDNAME, sizeof(info->driver));
+ strncpy(info->version, version, sizeof(info->version));
+- strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
++ strncpy(info->bus_info, dev->class_dev.dev->bus_id,
++ sizeof(info->bus_info));
+ }
+
+ static int smc_ethtool_nwayreset(struct net_device *dev)
+ {
+ struct smc_local *lp = netdev_priv(dev);
+@@ -1837,11 +1847,11 @@ static int __init smc_findirq(void __iom
+ * o set up my private data
+ * o configure the dev structure with my subroutines
+ * o actually GRAB the irq.
+ * o GRAB the region
+ */
+-static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
++int __init smc_probe(struct net_device *dev, void __iomem * ioaddr)
+ {
+ struct smc_local *lp = netdev_priv(dev);
+ static int version_printed = 0;
+ int i, retval;
+ unsigned int val, revision_register;
+@@ -1878,10 +1888,12 @@ static int __init smc_probe(struct net_d
+ * time won't hurt. This time, I need to switch the bank
+ * register to bank 1, so I can access the base address
+ * register
+ */
+ SMC_SELECT_BANK(1);
++ mdelay(100);
++ val = SMC_CURRENT_BANK();
+ val = SMC_GET_BASE();
+ val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
+ if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
+ printk("%s: IOADDR %p doesn't match configuration (%x).\n",
+ CARDNAME, ioaddr, val);
+@@ -1916,10 +1928,11 @@ static int __init smc_probe(struct net_d
+ lp->version = revision_register & 0xff;
+ spin_lock_init(&lp->lock);
+
+ /* Get the MAC address */
+ SMC_SELECT_BANK(1);
++
+ SMC_GET_MAC_ADDR(dev->dev_addr);
+
+ /* now, reset the chip, and put it into a known state */
+ smc_reset(dev);
+
+@@ -2003,11 +2016,15 @@ static int __init smc_probe(struct net_d
+ lp->ctl_rfduplx = 1;
+ lp->ctl_rspeed = 100;
+ }
+
+ /* Grab the IRQ */
+- retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
++ printk("dev->irq = %d\n", dev->irq);
++
++ retval =
++ request_irq(dev->irq, smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
++
+ if (retval)
+ goto err_out;
+
+ #ifdef SMC_USE_PXA_DMA
+ {
+@@ -2043,11 +2060,12 @@ static int __init smc_probe(struct net_d
+ }
+
+ if (lp->phy_type == 0) {
+ PRINTK("%s: No PHY found\n", dev->name);
+ } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) {
+- PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name);
++ PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n",
++ dev->name);
+ } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
+ PRINTK("%s: PHY LAN83C180\n", dev->name);
+ }
+ }
+
+@@ -2064,11 +2082,12 @@ static int smc_enable_device(struct plat
+ unsigned long flags;
+ unsigned char ecor, ecsr;
+ void __iomem *addr;
+ struct resource * res;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++ res =
++ platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+ if (!res)
+ return 0;
+
+ /*
+ * Map the attribute space. This is overkill, but clean.
+@@ -2120,11 +2139,12 @@ static int smc_enable_device(struct plat
+ return 0;
+ }
+
+ static int smc_request_attrib(struct platform_device *pdev)
+ {
+- struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++ struct resource *res =
++ platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+
+ if (!res)
+ return 0;
+
+ if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME))
+@@ -2133,11 +2153,12 @@ static int smc_request_attrib(struct pla
+ return 0;
+ }
+
+ static void smc_release_attrib(struct platform_device *pdev)
+ {
+- struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++ struct resource *res =
++ platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+
+ if (res)
+ release_mem_region(res->start, ATTRIB_SIZE);
+ }
+
+@@ -2157,12 +2178,16 @@ static inline void smc_request_datacs(st
+
+ lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
+ }
+ }
+
+-static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
++static void smc_release_datacs(struct platform_device *pdev,
++ struct net_device *ndev)
+ {
++// struct smc_local *lp = netdev_priv(ndev);
++// struct resource *res =
++// platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
+ if (SMC_CAN_USE_DATACS) {
+ struct smc_local *lp = netdev_priv(ndev);
+ struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
+
+ if (lp->datacs)
+@@ -2199,11 +2224,10 @@ static int smc_drv_probe(struct platform
+ if (!res) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+-
+ if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+@@ -2238,10 +2262,11 @@ static int smc_drv_probe(struct platform
+ ret = -ENOMEM;
+ goto out_release_attrib;
+ }
+
+ platform_set_drvdata(pdev, ndev);
++
+ ret = smc_probe(ndev, addr);
+ if (ret != 0)
+ goto out_iounmap;
+ #ifdef SMC_USE_PXA_DMA
+ else {
+@@ -2276,11 +2301,10 @@ static int smc_drv_remove(struct platfor
+ struct resource *res;
+
+ platform_set_drvdata(pdev, NULL);
+
+ unregister_netdev(ndev);
+-
+ free_irq(ndev->irq, ndev);
+
+ #ifdef SMC_USE_PXA_DMA
+ if (ndev->dma != (unsigned char)-1)
+ pxa_free_dma(ndev->dma);
+@@ -2346,12 +2370,10 @@ static int __init smc_init(void)
+ {
+ #ifdef MODULE
+ #ifdef CONFIG_ISA
+ if (io == -1)
+ printk(KERN_WARNING
+- "%s: You shouldn't use auto-probing with insmod!\n",
+- CARDNAME);
+ #endif
+ #endif
+
+ return platform_driver_register(&smc_driver);
+ }
+--- linux-2.6.20.orig/drivers/net/smc91x.h
++++ linux-2.6.20/drivers/net/smc91x.h
+@@ -32,11 +32,10 @@
+ .
+ ---------------------------------------------------------------------------*/
+ #ifndef _SMC91X_H_
+ #define _SMC91X_H_
+
+-
+ /*
+ * Define your architecture specific bus configuration parameters here.
+ */
+
+ #if defined(CONFIG_ARCH_LUBBOCK)
+@@ -161,12 +160,11 @@
+ #define SMC_outl(v, a, r) writel(v, (a) + (r))
+ #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
+ #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+
+ /* We actually can't write halfwords properly if not word aligned */
+-static inline void
+-SMC_outw(u16 val, void __iomem *ioaddr, int reg)
++static inline void SMC_outw(u16 val, void __iomem * ioaddr, int reg)
+ {
+ if (reg & 2) {
+ unsigned int v = val << 16;
+ v |= readl(ioaddr + (reg & ~2)) & 0xffff;
+ writel(v, ioaddr + (reg & ~2));
+@@ -197,10 +195,81 @@ SMC_outw(u16 val, void __iomem *ioaddr,
+ || machine_is_omap_h3() \
+ || machine_is_omap_h4() \
+ || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
+ ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
+
++#elif defined(CONFIG_ARCH_NOMADIK)
++
++#include <asm/hardware.h>
++
++#define SMC_CAN_USE_8BIT 0
++#define SMC_CAN_USE_16BIT 1
++#define SMC_CAN_USE_32BIT 0
++#define SMC_IO_SHIFT 0
++#define SMC_NOWAIT 0
++
++#define SMC_inb(a, r) readb((a) + (r))
++#define SMC_outb(v, a, r) writeb(v, (a) + (r))
++#define SMC_inw(a, r) readw((a) + (r))
++#define SMC_outw(v, a, r) writew(v, (a) + (r))
++#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
++#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
++#define SMC_inl(a, r) readl((a) + (r))
++#define SMC_outl(v, a, r) writel(v, (a) + (r))
++#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
++#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
++
++#ifdef CONFIG_NOMADIK_NHK15
++#define SMC_IRQ_FLAGS SA_TRIGGER_RISING
++#else
++#define SMC_IRQ_FLAGS (SA_SHIRQ)
++#endif
++
++static unsigned char new_mac_addr[MAX_ADDR_LEN] =
++ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
++
++static int smc_mac_setup(char *opt)
++{
++ char *cur = opt, *delim;
++ if (*cur != 0) {
++ /* Get the new MAC address */
++ if ((delim = strchr(cur, ':')) == NULL)
++ goto parse_failed;
++ *delim = 0;
++ new_mac_addr[0] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++ new_mac_addr[0] &= 0xFE; /* clear multicast bit */
++ new_mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
++ cur = delim + 1;
++ if ((delim = strchr(cur, ':')) == NULL)
++ goto parse_failed;
++ *delim = 0;
++ new_mac_addr[1] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++ cur = delim + 1;
++ if ((delim = strchr(cur, ':')) == NULL)
++ goto parse_failed;
++ *delim = 0;
++ new_mac_addr[2] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++ cur = delim + 1;
++ if ((delim = strchr(cur, ':')) == NULL)
++ goto parse_failed;
++ *delim = 0;
++ new_mac_addr[3] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++ cur = delim + 1;
++ if ((delim = strchr(cur, ':')) == NULL)
++ goto parse_failed;
++ *delim = 0;
++ new_mac_addr[4] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++ cur = delim + 1;
++ new_mac_addr[5] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++ }
++ return 0;
++parse_failed:
++ printk(KERN_INFO "mac=: couldn't parse config at %s!\n", cur);
++ return -1;
++}
++
++__setup("mac=", smc_mac_setup);
+
+ #elif defined(CONFIG_SH_SH4202_MICRODEV)
+
+ #define SMC_CAN_USE_8BIT 0
+ #define SMC_CAN_USE_16BIT 1
+@@ -475,24 +544,25 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ {
+ DCSR(dma) = 0;
+ }
+ #endif /* SMC_USE_PXA_DMA */
+
+-
+ /*
+ * Everything a particular hardware setup needs should have been defined
+ * at this point. Add stubs for the undefined cases, mainly to avoid
+ * compilation warnings since they'll be optimized away, or to prevent buggy
+ * use of them.
+ */
+
++#if 0 /*Vaibhav*/
+ #if ! SMC_CAN_USE_32BIT
+ #define SMC_inl(ioaddr, reg) ({ BUG(); 0; })
+ #define SMC_outl(x, ioaddr, reg) BUG()
+ #define SMC_insl(a, r, p, l) BUG()
+ #define SMC_outsl(a, r, p, l) BUG()
+ #endif
++#endif
+
+ #if !defined(SMC_insl) || !defined(SMC_outsl)
+ #define SMC_insl(a, r, p, l) BUG()
+ #define SMC_outsl(a, r, p, l) BUG()
+ #endif
+@@ -520,18 +590,22 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define SMC_insw(a, r, p, l) BUG()
+ #define SMC_outsw(a, r, p, l) BUG()
+
+ #endif
+
++#if 0 /*Vaibhav*/
+ #if !defined(SMC_insw) || !defined(SMC_outsw)
+ #define SMC_insw(a, r, p, l) BUG()
+ #define SMC_outsw(a, r, p, l) BUG()
+ #endif
++#endif
+
+ #if ! SMC_CAN_USE_8BIT
++#if 0 /*Vaibhav*/
+ #define SMC_inb(ioaddr, reg) ({ BUG(); 0; })
+ #define SMC_outb(x, ioaddr, reg) BUG()
++#endif
+ #define SMC_insb(a, r, p, l) BUG()
+ #define SMC_outsb(a, r, p, l) BUG()
+ #endif
+
+ #if !defined(SMC_insb) || !defined(SMC_outsb)
+@@ -567,11 +641,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ . xx = bank number
+ . yyyy yyyy = 0x33, for identification purposes.
+ */
+ #define BANK_SELECT (14 << SMC_IO_SHIFT)
+
+-
+ // Transmit Control Register
+ /* BANK 0 */
+ #define TCR_REG SMC_REG(0x0000, 0)
+ #define TCR_ENABLE 0x0001 // When 1 we can transmit
+ #define TCR_LOOP 0x0002 // Controls output pin LBK
+@@ -586,11 +659,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+
+ #define TCR_CLEAR 0 /* do NOTHING */
+ /* the default settings for the TCR register : */
+ #define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN)
+
+-
+ // EPH Status Register
+ /* BANK 0 */
+ #define EPH_STATUS_REG SMC_REG(0x0002, 0)
+ #define ES_TX_SUC 0x0001 // Last TX was successful
+ #define ES_SNGL_COL 0x0002 // Single collision detected for last tx
+@@ -605,11 +677,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define ES_EXC_DEF 0x0800 // Excessive Deferral
+ #define ES_CTR_ROL 0x1000 // Counter Roll Over indication
+ #define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin
+ #define ES_TXUNRN 0x8000 // Tx Underrun
+
+-
+ // Receive Control Register
+ /* BANK 0 */
+ #define RCR_REG SMC_REG(0x0004, 0)
+ #define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted
+ #define RCR_PRMS 0x0002 // Enable promiscuous mode
+@@ -622,21 +693,18 @@ smc_pxa_dma_irq(int dma, void *dummy)
+
+ /* the normal settings for the RCR register : */
+ #define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN)
+ #define RCR_CLEAR 0x0 // set it to a base state
+
+-
+ // Counter Register
+ /* BANK 0 */
+ #define COUNTER_REG SMC_REG(0x0006, 0)
+
+-
+ // Memory Information Register
+ /* BANK 0 */
+ #define MIR_REG SMC_REG(0x0008, 0)
+
+-
+ // Receive/Phy Control Register
+ /* BANK 0 */
+ #define RPC_REG SMC_REG(0x000A, 0)
+ #define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode.
+ #define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode
+@@ -659,18 +727,16 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define RPC_LSB_DEFAULT RPC_LED_FD
+ #endif
+
+ #define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
+
+-
+ /* Bank 0 0x0C is reserved */
+
+ // Bank Select Register
+ /* All Banks */
+ #define BSR_REG 0x000E
+
+-
+ // Configuration Reg
+ /* BANK 1 */
+ #define CONFIG_REG SMC_REG(0x0000, 1)
+ #define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy
+ #define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL
+@@ -678,28 +744,24 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode.
+
+ // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
+ #define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
+
+-
+ // Base Address Register
+ /* BANK 1 */
+ #define BASE_REG SMC_REG(0x0002, 1)
+
+-
+ // Individual Address Registers
+ /* BANK 1 */
+ #define ADDR0_REG SMC_REG(0x0004, 1)
+ #define ADDR1_REG SMC_REG(0x0006, 1)
+ #define ADDR2_REG SMC_REG(0x0008, 1)
+
+-
+ // General Purpose Register
+ /* BANK 1 */
+ #define GP_REG SMC_REG(0x000A, 1)
+
+-
+ // Control Register
+ /* BANK 1 */
+ #define CTL_REG SMC_REG(0x000C, 1)
+ #define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received
+ #define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
+@@ -708,11 +770,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt
+ #define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store
+ #define CTL_RELOAD 0x0002 // When set reads EEPROM into registers
+ #define CTL_STORE 0x0001 // When set stores registers into EEPROM
+
+-
+ // MMU Command Register
+ /* BANK 2 */
+ #define MMU_CMD_REG SMC_REG(0x0000, 2)
+ #define MC_BUSY 1 // When 1 the last release has not completed
+ #define MC_NOP (0<<5) // No Op
+@@ -722,22 +783,19 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define MC_RELEASE (4<<5) // Remove and release the current rx packet
+ #define MC_FREEPKT (5<<5) // Release packet in PNR register
+ #define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit
+ #define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs
+
+-
+ // Packet Number Register
+ /* BANK 2 */
+ #define PN_REG SMC_REG(0x0002, 2)
+
+-
+ // Allocation Result Register
+ /* BANK 2 */
+ #define AR_REG SMC_REG(0x0003, 2)
+ #define AR_FAILED 0x80 // Alocation Failed
+
+-
+ // TX FIFO Ports Register
+ /* BANK 2 */
+ #define TXFIFO_REG SMC_REG(0x0004, 2)
+ #define TXFIFO_TEMPTY 0x80 // TX FIFO Empty
+
+@@ -753,21 +811,18 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define PTR_REG SMC_REG(0x0006, 2)
+ #define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area
+ #define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access
+ #define PTR_READ 0x2000 // When 1 the operation is a read
+
+-
+ // Data Register
+ /* BANK 2 */
+ #define DATA_REG SMC_REG(0x0008, 2)
+
+-
+ // Interrupt Status/Acknowledge Register
+ /* BANK 2 */
+ #define INT_REG SMC_REG(0x000C, 2)
+
+-
+ // Interrupt Mask Register
+ /* BANK 2 */
+ #define IM_REG SMC_REG(0x000D, 2)
+ #define IM_MDINT 0x80 // PHY MI Register 18 Interrupt
+ #define IM_ERCV_INT 0x40 // Early Receive Interrupt
+@@ -776,48 +831,42 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define IM_ALLOC_INT 0x08 // Set when allocation request is completed
+ #define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty
+ #define IM_TX_INT 0x02 // Transmit Interrupt
+ #define IM_RCV_INT 0x01 // Receive Interrupt
+
+-
+ // Multicast Table Registers
+ /* BANK 3 */
+ #define MCAST_REG1 SMC_REG(0x0000, 3)
+ #define MCAST_REG2 SMC_REG(0x0002, 3)
+ #define MCAST_REG3 SMC_REG(0x0004, 3)
+ #define MCAST_REG4 SMC_REG(0x0006, 3)
+
+-
+ // Management Interface Register (MII)
+ /* BANK 3 */
+ #define MII_REG SMC_REG(0x0008, 3)
+ #define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup
+ #define MII_MDOE 0x0008 // MII Output Enable
+ #define MII_MCLK 0x0004 // MII Clock, pin MDCLK
+ #define MII_MDI 0x0002 // MII Input, pin MDI
+ #define MII_MDO 0x0001 // MII Output, pin MDO
+
+-
+ // Revision Register
+ /* BANK 3 */
+ /* ( hi: chip id low: rev # ) */
+ #define REV_REG SMC_REG(0x000A, 3)
+
+-
+ // Early RCV Register
+ /* BANK 3 */
+ /* this is NOT on SMC9192 */
+ #define ERCV_REG SMC_REG(0x000C, 3)
+ #define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received
+ #define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask
+
+-
+ // External Register
+ /* BANK 7 */
+ #define EXT_REG SMC_REG(0x0000, 7)
+
+-
+ #define CHIP_9192 3
+ #define CHIP_9194 4
+ #define CHIP_9195 5
+ #define CHIP_9196 6
+ #define CHIP_91100 7
+@@ -832,12 +881,12 @@ static const char * chip_ids[ 16 ] = {
+ /* 6 */ "SMC91C96",
+ /* 7 */ "SMC91C100",
+ /* 8 */ "SMC91C100FD",
+ /* 9 */ "SMC91C11xFD",
+ NULL, NULL, NULL,
+- NULL, NULL, NULL};
+-
++ NULL, NULL, NULL
++};
+
+ /*
+ . Receive status bits
+ */
+ #define RS_ALGNERR 0x8000
+@@ -847,11 +896,10 @@ static const char * chip_ids[ 16 ] = {
+ #define RS_TOOLONG 0x0800
+ #define RS_TOOSHORT 0x0400
+ #define RS_MULTICAST 0x0001
+ #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
+
+-
+ /*
+ * PHY IDs
+ * LAN83C183 == LAN91C111 Internal PHY
+ */
+ #define PHY_LAN83C183 0x0016f840
+@@ -877,11 +925,10 @@ static const char * chip_ids[ 16 ] = {
+ #define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db
+ #define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust
+ #define PHY_CFG1_TLVL_MASK 0x003C
+ #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time
+
+-
+ // PHY Configuration Register 2
+ #define PHY_CFG2_REG 0x11
+ #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled
+ #define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled
+ #define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt)
+@@ -902,11 +949,10 @@ static const char * chip_ids[ 16 ] = {
+
+ // PHY Interrupt/Status Mask Register
+ #define PHY_MASK_REG 0x13 // Interrupt Mask
+ // Uses the same bit definitions as PHY_INT_REG
+
+-
+ /*
+ * SMC91C96 ethernet config and status registers.
+ * These are in the "attribute" space.
+ */
+ #define ECOR 0x8000
+@@ -920,11 +966,10 @@ static const char * chip_ids[ 16 ] = {
+ #define ECSR_PWRDWN 0x04
+ #define ECSR_INT 0x02
+
+ #define ATTRIB_SIZE ((64*1024) << SMC_IO_SHIFT)
+
+-
+ /*
+ * Macros to abstract register access according to the data bus
+ * capabilities. Please use those and not the in/out primitives.
+ * Note: the following macros do *not* select the bank -- this must
+ * be done separately as needed in the main code. The SMC_REG() macro
+@@ -1087,10 +1132,27 @@ static const char * chip_ids[ 16 ] = {
+ #define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG)
+
+ #define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG)
+
+ #ifndef SMC_GET_MAC_ADDR
++#ifdef CONFIG_ARCH_NOMADIK
++#define SMC_GET_MAC_ADDR(addr) \
++ if (new_mac_addr[0] == 0xFF) { \
++ printk("%s: Setting Random MAC addr\n", CARDNAME); \
++ random_ether_addr(new_mac_addr); \
++ } \
++ SMC_SET_MAC_ADDR(new_mac_addr); \
++ do { \
++ unsigned int __v; \
++ __v = SMC_inw( ioaddr, ADDR0_REG ); \
++ addr[0] = __v; addr[1] = __v >> 8; \
++ __v = SMC_inw( ioaddr, ADDR1_REG ); \
++ addr[2] = __v; addr[3] = __v >> 8; \
++ __v = SMC_inw( ioaddr, ADDR2_REG ); \
++ addr[4] = __v; addr[5] = __v >> 8; \
++ } while (0)
++#else
+ #define SMC_GET_MAC_ADDR(addr) \
+ do { \
+ unsigned int __v; \
+ __v = SMC_inw( ioaddr, ADDR0_REG ); \
+ addr[0] = __v; addr[1] = __v >> 8; \
+@@ -1098,10 +1160,11 @@ static const char * chip_ids[ 16 ] = {
+ addr[2] = __v; addr[3] = __v >> 8; \
+ __v = SMC_inw( ioaddr, ADDR2_REG ); \
+ addr[4] = __v; addr[5] = __v >> 8; \
+ } while (0)
+ #endif
++#endif
+
+ #define SMC_SET_MAC_ADDR(addr) \
+ do { \
+ SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG ); \
+ SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG ); \
+--- linux-2.6.20.orig/drivers/serial/amba-pl011.c
++++ linux-2.6.20/drivers/serial/amba-pl011.c
+@@ -50,17 +50,36 @@
+ #include <linux/amba/serial.h>
+ #include <linux/clk.h>
+
+ #include <asm/io.h>
+ #include <asm/sizes.h>
++#include <asm/mach-types.h>
++#include <asm/hardware.h>
+
+-#define UART_NR 14
++/*
++ * Definations here is used instead of this which is defined in platform.h
++ */
++
++#ifndef UART_NR
++#define UART_NR 14 /*default generic value */
++#endif
++
++#ifndef UART_FIFO_SIZE
++#define UART_FIFO_SIZE 16 /*default generic value */
++#endif
++
++#ifndef UART_PER_ID
++#define UART_PER_ID 0x00041011 /*default uart peripharal id */
++#endif
++
++#ifndef UART_PER_MASK
++#define UART_PER_MASK 0x000fffff /*default uart peripharal mask */
++#endif
+
+ #define SERIAL_AMBA_MAJOR 204
+ #define SERIAL_AMBA_MINOR 64
+ #define SERIAL_AMBA_NR UART_NR
+-
+ #define AMBA_ISR_PASS_LIMIT 256
+
+ #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
+ #define UART_DUMMY_DR_RX (1 << 16)
+
+@@ -100,23 +119,31 @@ static void pl011_stop_rx(struct uart_po
+ }
+
+ static void pl011_enable_ms(struct uart_port *port)
+ {
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
++ unsigned cr;
+
+- uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
++ uap->im |=
++ UART011_RIMIM | UART011_CTSMIM | UART011_DCDMIM | UART011_DSRMIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
++
++ cr = readw(uap->port.membase + UART011_CR);
++ barrier();
++ cr = cr | UART_CONTROL_MASK_CTSFLOW | UART_CONTROL_MASK_RTSFLOW;
++ writew(cr, uap->port.membase + UART011_CR);
+ }
+
+ static void pl011_rx_chars(struct uart_amba_port *uap)
+ {
+ struct tty_struct *tty = uap->port.info->tty;
+ unsigned int status, ch, flag, max_count = 256;
+
+ status = readw(uap->port.membase + UART01x_FR);
+ while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
+ ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
++
+ flag = TTY_NORMAL;
+ uap->port.icount.rx++;
+
+ /*
+ * Note that the error handling code is
+@@ -172,11 +199,13 @@ static void pl011_tx_chars(struct uart_a
+ pl011_stop_tx(&uap->port);
+ return;
+ }
+
+ count = uap->port.fifosize >> 1;
++
+ do {
++
+ writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ uap->port.icount.tx++;
+ if (uart_circ_empty(xmit))
+ break;
+@@ -316,10 +345,11 @@ static void pl011_break_ctl(struct uart_
+ static int pl011_startup(struct uart_port *port)
+ {
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+ unsigned int cr;
+ int retval;
++ int status, ch;
+
+ /*
+ * Try to enable the clock producer.
+ */
+ retval = clk_enable(uap->clk);
+@@ -329,36 +359,54 @@ static int pl011_startup(struct uart_por
+ uap->port.uartclk = clk_get_rate(uap->clk);
+
+ /*
+ * Allocate the IRQ
+ */
+- retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
++ retval =
++ request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap);
+ if (retval)
+ goto clk_dis;
+
+- writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
+- uap->port.membase + UART011_IFLS);
++ /*
++ *writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
++ *uap->port.membase + UART011_IFLS);
++ */
++
++ writew(UART_TX_RX_HALF, uap->port.membase + UART011_IFLS);
++ /* Clearing interrupts */
++ writew(0x7ff, uap->port.membase + UART011_ICR);
+
+ /*
+ * Provoke TX FIFO interrupt into asserting.
+ */
+ cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
+ writew(cr, uap->port.membase + UART011_CR);
+ writew(0, uap->port.membase + UART011_FBRD);
+ writew(1, uap->port.membase + UART011_IBRD);
+ writew(0, uap->port.membase + UART011_LCRH);
+- writew(0, uap->port.membase + UART01x_DR);
++ writew('Z', uap->port.membase + UART01x_DR);
++
++ barrier();
++ ch = readw(uap->port.membase + UART01x_DR);
++
+ while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
+ barrier();
+
+ cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
+ writew(cr, uap->port.membase + UART011_CR);
+
+ /*
+ * initialise the old status of the modem signals
+ */
+- uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
++ uap->old_status =
++ readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
++
++ status = readw(uap->port.membase + UART01x_FR);
++ while ((status & UART01x_FR_RXFE) == 0) {
++ ch = readw(uap->port.membase + UART01x_DR);
++ status = readw(uap->port.membase + UART01x_FR);
++ }
+
+ /*
+ * Finally, enable interrupts
+ */
+ spin_lock_irq(&uap->port.lock);
+@@ -394,11 +442,12 @@ static void pl011_shutdown(struct uart_p
+ free_irq(uap->port.irq, uap);
+
+ /*
+ * disable the port
+ */
+- writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
++ writew(UART01x_CR_UARTEN | UART011_CR_TXE,
++ uap->port.membase + UART011_CR);
+
+ /*
+ * disable break condition and fifos
+ */
+ val = readw(uap->port.membase + UART011_LCRH);
+@@ -656,10 +705,11 @@ static int __init pl011_console_setup(st
+ /*
+ * Check whether an invalid uart number has been specified, and
+ * if so, search for the first available port that does have
+ * console support.
+ */
++
+ if (co->index >= UART_NR)
+ co->index = 0;
+ uap = amba_ports[co->index];
+ if (!uap)
+ return -ENODEV;
+@@ -698,10 +748,32 @@ static struct uart_driver amba_reg = {
+ .minor = SERIAL_AMBA_MINOR,
+ .nr = UART_NR,
+ .cons = AMBA_CONSOLE,
+ };
+
++#ifdef CONFIG_PM
++static int pl011_suspend(struct amba_device *dev, pm_message_t state)
++{
++ struct uart_amba_port *uap = amba_get_drvdata(dev);
++
++ if (uap)
++ uart_suspend_port(&amba_reg, &uap->port);
++
++ return 0;
++}
++
++static int pl011_resume(struct amba_device *dev)
++{
++ struct uart_amba_port *uap = amba_get_drvdata(dev);
++
++ if (uap)
++ uart_resume_port(&amba_reg, &uap->port);
++
++ return 0;
++}
++#endif
++
+ static int pl011_probe(struct amba_device *dev, void *id)
+ {
+ struct uart_amba_port *uap;
+ void __iomem *base;
+ int i, ret;
+@@ -737,13 +809,14 @@ static int pl011_probe(struct amba_devic
+ uap->port.dev = &dev->dev;
+ uap->port.mapbase = dev->res.start;
+ uap->port.membase = base;
+ uap->port.iotype = UPIO_MEM;
+ uap->port.irq = dev->irq[0];
+- uap->port.fifosize = 16;
++ uap->port.fifosize = UART_FIFO_SIZE;
+ uap->port.ops = &amba_pl011_pops;
+ uap->port.flags = UPF_BOOT_AUTOCONF;
++
+ uap->port.line = i;
+
+ amba_ports[i] = uap;
+
+ amba_set_drvdata(dev, uap);
+@@ -780,12 +853,12 @@ static int pl011_remove(struct amba_devi
+ return 0;
+ }
+
+ static struct amba_id pl011_ids[] __initdata = {
+ {
+- .id = 0x00041011,
+- .mask = 0x000fffff,
++ .id = UART_PER_ID,
++ .mask = UART_PER_MASK,
+ },
+ { 0, 0 },
+ };
+
+ static struct amba_driver pl011_driver = {
+@@ -793,10 +866,14 @@ static struct amba_driver pl011_driver =
+ .name = "uart-pl011",
+ },
+ .id_table = pl011_ids,
+ .probe = pl011_probe,
+ .remove = pl011_remove,
++#ifdef CONFIG_PM
++ .suspend = pl011_suspend,
++ .resume = pl011_resume,
++#endif
+ };
+
+ static int __init pl011_init(void)
+ {
+ int ret;
+--- linux-2.6.20.orig/drivers/spi/Kconfig
++++ linux-2.6.20/drivers/spi/Kconfig
+@@ -63,10 +63,18 @@ config SPI_BITBANG
+
+ This is library code, and is automatically selected by drivers that
+ need it. You only need to select this explicitly to support driver
+ modules that aren't part of this kernel tree.
+
++config NOMADIK_SPI
++ tristate "Nomadik SPI master"
++ depends on SPI_MASTER && EXPERIMENTAL
++ default y
++ help
++ This enables using the Nomadik SPI controller in master
++ mode.
++
+ config SPI_BUTTERFLY
+ tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
+ depends on SPI_MASTER && PARPORT && EXPERIMENTAL
+ select SPI_BITBANG
+ help
+--- linux-2.6.20.orig/drivers/spi/Makefile
++++ linux-2.6.20/drivers/spi/Makefile
+@@ -10,10 +10,12 @@ endif
+ # config declarations into driver model code
+ obj-$(CONFIG_SPI_MASTER) += spi.o
+
+ # SPI master controller drivers (bus)
+ obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
++obj-$(CONFIG_NOMADIK_SPI) += nmdkmod_spi.o
++nmdkmod_spi-objs := spi-nomadik.o
+ obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
+ obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
+ obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
+ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
+ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
+--- /dev/null
++++ linux-2.6.20/drivers/spi/spi-nomadik.c
+@@ -0,0 +1,1000 @@
++/*
++ * drivers/spi/spi-nomadik.c
++ *
++ * Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
++ *
++ * Author: Sachin Verma <sachin.verma@st.com>
++ * Vaibhav Agarwal <vaibhav.agarwal@st.com
++ * Initial version inspired by:
++ * linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/ioport.h>
++#include <linux/errno.h>
++#include <linux/platform_device.h>
++#include <linux/amba/bus.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/hardware.h>
++#include <asm/delay.h>
++
++#include <asm/arch/hardware.h>
++#include <asm/arch/defs.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/spi.h>
++#include <asm/arch/debug.h>
++#include <asm/arch/ssp-spi.h>
++#include <asm/arch/msp-spi.h>
++#include <asm/arch/msp.h>
++
++/***************************************************************************/
++
++#define NMDK_SPI_NAME "NOMADIK_SPI"
++
++#ifndef SPI_DEBUG
++#define SPI_DEBUG 0
++#endif
++
++#define NMDK_DEBUG SPI_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX NMDK_SPI_NAME /* msg header represents this module */
++#define NMDK_DBG KERN_ERR /* message level */
++
++/***************************************************************************/
++
++#define FALSE (0)
++#define TRUE (1)
++
++#define DO_NOT_QUEUE_DMA (0)
++#define QUEUE_DMA (1)
++
++/*#######################################################################
++ Queue State
++#########################################################################
++ */
++#define QUEUE_RUNNING (0)
++#define QUEUE_STOPPED (1)
++
++/***************************************************************************/
++static void print_dma_info(u32 xfer_type, struct chip_data *chip){
++ nmdk_dbg("Rx Pipe : mode = %08x\n", chip->dma_info->rx_dma_info.mode);
++ nmdk_dbg("Rx Pipe : config = %08x\n", chip->dma_info->rx_dma_info.config);
++ nmdk_dbg("Rx Pipe : srcdevtype = %s\n", chip->dma_info->rx_dma_info.srcdevtype);
++ nmdk_dbg("Rx Pipe : destdevtype = %s\n", chip->dma_info->rx_dma_info.destdevtype);
++
++ nmdk_dbg("Tx Pipe : mode = %08x\n", chip->dma_info->tx_dma_info.mode);
++ nmdk_dbg("Tx Pipe : config = %08x\n", chip->dma_info->tx_dma_info.config);
++ nmdk_dbg("Tx Pipe : srcdevtype = %s\n", chip->dma_info->tx_dma_info.srcdevtype);
++ nmdk_dbg("Tx Pipe : destdevtype = %s\n", chip->dma_info->tx_dma_info.destdevtype);
++}
++/***************************************************************************/
++
++/**
++ * null_cs_control - Dummy chip select function
++ * @command: select/delect the chip
++ *
++ * If no chip select function is provided by client this is used as dummy
++ * chip select
++ */
++void null_cs_control(u32 command)
++{
++ nmdk_dbg_ftrace();
++ nmdk_dbg("::::Dummy chip select control\n");
++}
++EXPORT_SYMBOL(null_cs_control);
++
++void nomadik_spi_tasklet(unsigned long param)
++{
++ struct driver_data *drv_data = (struct driver_data *)param;
++ struct spi_message *msg = drv_data->cur_msg;
++ struct spi_transfer *previous = NULL;
++ /*DMA complete. schedule next xfer */
++ /*DISABLE DMA, and flush FIFO of SPI Controller */
++ drv_data->execute_cmd(drv_data, DISABLE_DMA);
++ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++ msg->actual_length += drv_data->cur_transfer->len;
++ if (drv_data->cur_transfer->cs_change)
++ drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
++ msg->state = next_transfer(drv_data);
++ if (msg->state == ERROR_STATE)
++ goto handle_dma_error;
++ else if (msg->state == DONE_STATE) {
++ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++ msg->status = 0;
++ giveback(msg, drv_data);
++ return ;
++ }
++ /* Delay if requested at end of transfer */
++ else if (msg->state == RUNNING_STATE) {
++ previous =
++ list_entry(drv_data->cur_transfer->transfer_list.
++ prev, struct spi_transfer,
++ transfer_list);
++ if (previous->delay_usecs)
++ udelay(previous->delay_usecs);
++ if (previous->cs_change)
++ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++ } else goto handle_dma_error;
++
++ if (drv_data->cur_transfer->tx_dma) {
++ atomic_inc(&drv_data->dma_cnt);
++ __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach, (dma_addr_t) (drv_data->cur_transfer->tx_dma));
++ __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
++ (dma_addr_t) (drv_data->master_info->dma_srcaddr));
++ set_dma_count(drv_data->cur_chip->dma_info->tx_dmach, (drv_data->cur_transfer->len));
++ enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
++ }
++ if (drv_data->cur_transfer->rx_dma) {
++ atomic_inc(&drv_data->dma_cnt);
++ __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
++ (dma_addr_t) (drv_data->master_info->dma_destaddr));
++ __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach, (dma_addr_t) (drv_data->cur_transfer->rx_dma));
++ set_dma_count(drv_data->cur_chip->dma_info->rx_dmach, (drv_data->cur_transfer->len));
++ enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
++ }
++ /*Enable DMA for this chip */
++ drv_data->execute_cmd(drv_data, ENABLE_DMA);
++ return ;
++
++ handle_dma_error:
++ atomic_set(&drv_data->dma_cnt, 0);
++ drv_data->execute_cmd(drv_data, DISABLE_DMA);
++ msg->status = -EIO;
++ giveback(msg, drv_data);
++ return ;
++}
++EXPORT_SYMBOL(nomadik_spi_tasklet);
++
++/**
++ * spi_dma_callback_handler - This function is invoked when dma xfer is complete
++ * @param: context data which is drivers private data
++ * @event: Status of current DMA transfer
++ *
++ * This function checks if DMA transfer is complete for current transfer
++ * It fills the Rx Tx buffer pointers again and launch dma for next
++ * transfer from this callback handler itself
++ *
++ */
++irqreturn_t spi_dma_callback_handler(int irq, void *param)
++{
++ struct driver_data *drv_data = (struct driver_data *)param;
++ int flag = 0;
++
++ nmdk_dbg_ftrace();
++
++ smp_mb();
++ if (atomic_dec_and_test(&drv_data->dma_cnt)) {
++ flag = 1;
++ }
++ smp_mb();
++ if (flag == 1) {
++ tasklet_schedule(&drv_data->spi_dma_tasklet);
++ }
++ return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(spi_dma_callback_handler);
++
++/**
++ * giveback - current spi_message is over, schedule next spi_message and call callback of this msg
++ * @message: current SPI message
++ * @drv_data: spi driver private data structure
++ *
++ */
++void giveback(struct spi_message *message, struct driver_data *drv_data)
++{
++ struct spi_transfer *last_transfer;
++ unsigned long flags;
++ struct spi_message *msg;
++ void (*curr_cs_control) (u32 command);
++
++ spin_lock_irqsave(&drv_data->lock, flags);
++ msg = drv_data->cur_msg;
++
++ curr_cs_control = drv_data->cur_chip->cs_control;
++ drv_data->cur_msg = NULL;
++ drv_data->cur_transfer = NULL;
++ drv_data->cur_chip = NULL;
++#ifdef SPI_WORKQUEUE
++ queue_work(drv_data->workqueue, &drv_data->spi_work);
++#endif
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++
++ schedule_work(&drv_data->spi_work);
++
++ last_transfer = list_entry(msg->transfers.prev,
++ struct spi_transfer, transfer_list);
++ if (!last_transfer->cs_change)
++ curr_cs_control(SPI_CHIP_DESELECT);
++ msg->state = NULL;
++ if (msg->complete)
++ msg->complete(msg->context);
++ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++}
++EXPORT_SYMBOL(giveback);
++
++/**
++ * next_transfer - Move to the Next transfer in the current spi message
++ * @drv_data: spi driver private data structure
++ *
++ * This function moves though the linked list of spi transfers in the
++ * current spi message and returns with the state of current spi
++ * message i.e whether its last transfer is done(DONE_STATE) or
++ * Next transfer is ready(RUNNING_STATE)
++ */
++void *next_transfer(struct driver_data *drv_data)
++{
++ struct spi_message *msg = drv_data->cur_msg;
++ struct spi_transfer *trans = drv_data->cur_transfer;
++ /* Move to next transfer */
++ if (trans->transfer_list.next != &msg->transfers) {
++ drv_data->cur_transfer =
++ list_entry(trans->transfer_list.next,
++ struct spi_transfer, transfer_list);
++ return RUNNING_STATE;
++ }
++ return DONE_STATE;
++}
++EXPORT_SYMBOL(next_transfer);
++
++/**
++ * ssp_null_writer - To Write Dummy Data in Data register
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a write function for transfer which have
++ * Tx transfer buffer as NULL. It simply writes '0' in the Data
++ * register
++ */
++static void ssp_null_writer(struct driver_data *drv_data)
++{
++ while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF)
++ && (drv_data->tx < drv_data->tx_end)) {
++ /*Write '0' Data to Data Register */
++ writel(0x0, SSP_DR(drv_data->regs));
++ drv_data->tx += (drv_data->cur_chip->n_bytes);
++ }
++}
++
++/**
++ * ssp_null_reader - To read data from Data register and discard it
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a reader function for transfer which have
++ * Rx Transfer buffer as null. Read Data is rejected
++ *
++ */
++static void ssp_null_reader(struct driver_data *drv_data)
++{
++ while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE)
++ && (drv_data->rx < drv_data->rx_end)) {
++ readl(SSP_DR(drv_data->regs));
++ drv_data->rx += (drv_data->cur_chip->n_bytes);
++ }
++}
++
++/**
++ * msp_null_writer - To Write Dummy Data in Data register
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a write function for transfer which have
++ * Tx transfer buffer as NULL. It simply writes '0' in the Data
++ * register
++ */
++static void msp_null_writer(struct driver_data *drv_data)
++{
++ u32 cur_write = 0;
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
++ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++ return;
++ writel( 0x0, MSP_DR(drv_data->regs));
++ drv_data->tx += (drv_data->cur_chip->n_bytes);
++ cur_write ++;
++ if(cur_write == 8)
++ return;
++ }
++}
++
++/**
++ * msp_null_reader - To read data from Data register and discard it
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a reader function for transfer which have
++ * Rx Transfer buffer as null. Read Data is rejected
++ *
++ */
++static void msp_null_reader(struct driver_data *drv_data)
++{
++ u32 status;
++ while(1){
++ status = readl(MSP_FLR(drv_data->regs));
++ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++ return;
++ readl(MSP_DR(drv_data->regs));
++ drv_data->rx += (drv_data->cur_chip->n_bytes);
++ }
++}
++
++/**
++ * pump_transfers - Tasklet function which schedules next interrupt xfer
++ * @data: spi driver private data structure
++ *
++ */
++static void pump_transfers(unsigned long data)
++{
++ struct driver_data *drv_data = (struct driver_data *)data;
++ struct spi_message *message = NULL;
++ struct spi_transfer *transfer = NULL;
++ struct spi_transfer *previous = NULL;
++
++ nmdk_dbg_ftrace();
++
++ message = drv_data->cur_msg;
++ /* Handle for abort */
++ if (message->state == ERROR_STATE) {
++ message->status = -EIO;
++ giveback(message, drv_data);
++ return;
++ }
++ /* Handle end of message */
++ if (message->state == DONE_STATE) {
++ message->status = 0;
++ giveback(message, drv_data);
++ return;
++ }
++ transfer = drv_data->cur_transfer;
++ /* Delay if requested at end of transfer */
++ if (message->state == RUNNING_STATE) {
++ previous =
++ list_entry(transfer->transfer_list.prev,
++ struct spi_transfer, transfer_list);
++ if (previous->delay_usecs)
++ udelay(previous->delay_usecs);
++ if (previous->cs_change)
++ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++ } else {
++ /* START_STATE */
++ message->state = RUNNING_STATE;
++ }
++ drv_data->tx = (void *)transfer->tx_buf;
++ drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
++ drv_data->rx = (void *)transfer->rx_buf;
++ drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++
++ if(drv_data->master->bus_num == SSP_CONTROLLER){
++ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
++ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++ }
++ else{
++ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
++ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++ }
++
++ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++ drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
++}
++
++/**
++ * do_dma_transfer - It handles transfers of the current message if it is DMA xfer
++ * @data: spi driver's private data structure
++ *
++ *
++ *
++ */
++static void do_dma_transfer(void *data)
++{
++ struct driver_data *drv_data = (struct driver_data *)data;
++
++ atomic_set(&drv_data->dma_cnt, 0);
++ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++
++ if ((drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_MEM) ||
++ (drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_PERIPH)) {
++ if (drv_data->cur_chip->dma_info->tx_dmach >= 0) {
++ atomic_inc(&drv_data->dma_cnt);
++ __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach,
++ (dma_addr_t) (drv_data->cur_transfer->tx_dma));
++ __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
++ (dma_addr_t) (drv_data->master_info->dma_srcaddr));
++ set_dma_count(drv_data->cur_chip->dma_info->tx_dmach,
++ (drv_data->cur_transfer->len));
++ enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
++ }
++ if (drv_data->cur_chip->dma_info->rx_dmach >= 0) {
++ atomic_inc(&drv_data->dma_cnt);
++ __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
++ (dma_addr_t) (drv_data->master_info->dma_destaddr));
++ __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach,
++ (dma_addr_t) (drv_data->cur_transfer->rx_dma));
++ set_dma_count(drv_data->cur_chip->dma_info->rx_dmach,
++ (drv_data->cur_transfer->len));
++ enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
++ }
++ if((drv_data->cur_chip->dma_info->tx_dma_info.mode & DMA_INFINITE_XFER) &&
++ (drv_data->cur_chip->dma_info->rx_dma_info.mode & DMA_INFINITE_XFER)){
++ /*Only if it is an infinite transfer, we will deploy mechanism to stop it*/
++ nmdk_dbg("Only if it is an infinite transfer, we will deploy mechanism to stop it");
++ drv_data->dma_ongoing = 1;
++ }
++ } else {
++ nmdk_dbg(":::: Invalid DMA xfer type \n");
++ goto err_dma_transfer;
++ }
++ /*Enable SPI Controller */
++ drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++ return;
++
++ err_dma_transfer:
++ drv_data->cur_msg->state = ERROR_STATE;
++ drv_data->cur_msg->status = -EIO;
++ giveback(drv_data->cur_msg, drv_data);
++ return;
++}
++
++static void do_interrupt_transfer(void *data)
++{
++ struct driver_data *drv_data = (struct driver_data *)data;
++
++ drv_data->tx = (void *)drv_data->cur_transfer->tx_buf;
++ drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
++ drv_data->rx = (void *)drv_data->cur_transfer->rx_buf;
++ drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++
++ if(drv_data->master->bus_num == SSP_CONTROLLER){
++ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
++ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++ }
++ else{
++ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
++ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++ }
++
++ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++
++ drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
++ drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++}
++
++static void do_polling_transfer(void *data)
++{
++ struct driver_data *drv_data = (struct driver_data *)data;
++ struct spi_message *message = NULL;
++ struct spi_transfer *transfer = NULL;
++ struct spi_transfer *previous = NULL;
++ struct chip_data *chip;
++ unsigned long limit = 0;
++
++ chip = drv_data->cur_chip;
++ message = drv_data->cur_msg;
++
++ while (message->state != DONE_STATE) {
++ /* Handle for abort */
++ if (message->state == ERROR_STATE)
++ break;
++ transfer = drv_data->cur_transfer;
++
++ /* Delay if requested at end of transfer */
++ if (message->state == RUNNING_STATE) {
++ previous =
++ list_entry(transfer->transfer_list.prev,
++ struct spi_transfer, transfer_list);
++ if (previous->delay_usecs)
++ udelay(previous->delay_usecs);
++ if (previous->cs_change)
++ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++ } else {
++ /* START_STATE */
++ message->state = RUNNING_STATE;
++ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++ }
++
++ /*Configuration Changing Per Transfer */
++ drv_data->tx = (void *)transfer->tx_buf;
++ drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
++ drv_data->rx = (void *)transfer->rx_buf;
++ drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++
++ if(drv_data->master->bus_num == SSP_CONTROLLER){
++ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
++ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++ }
++ else{
++ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
++ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++ }
++
++ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++ drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++
++ nmdk_dbg(":::: POLLING TRANSFER ONGOING ... \n");
++ while (drv_data->tx < drv_data->tx_end) {
++ drv_data->read(drv_data);
++ drv_data->write(drv_data);
++ }
++
++ limit = loops_per_jiffy << 1;
++
++ while ((drv_data->rx < drv_data->rx_end) && (limit--)){
++ drv_data->read(drv_data);
++ }
++
++ /* Update total byte transfered */
++ message->actual_length += drv_data->cur_transfer->len;
++ if (drv_data->cur_transfer->cs_change)
++ drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
++ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++
++ /* Move to next transfer */
++ message->state = next_transfer(drv_data);
++ }
++
++ /* Handle end of message */
++ if (message->state == DONE_STATE)
++ message->status = 0;
++ else
++ message->status = -EIO;
++
++ giveback(message, drv_data);
++ return;
++}
++/**
++ * pump_messages - Workqueue function which processes spi message queue
++ * @data: pointer to private data of spi driver
++ *
++ * This function checks if there is any spi message in the queue that
++ * needs processing and delegate control to appropriate function
++ * do_polling_transfer()/do_interrupt_transfer()/do_dma_transfer()
++ * based on the kind of the transfer
++ *
++ */
++static void pump_messages(struct work_struct *work)
++{
++ struct driver_data *drv_data = container_of(work, struct driver_data,spi_work);
++ unsigned long flags;
++
++ /* Lock queue and check for queue work */
++ spin_lock_irqsave(&drv_data->lock, flags);
++ if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
++ nmdk_dbg(":::: work_queue: Queue Empty\n");
++ drv_data->busy = 0;
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ return;
++ }
++ /* Make sure we are not already running a message */
++ if (drv_data->cur_msg) {
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ return;
++ }
++
++ /* Extract head of queue */
++ drv_data->cur_msg =
++ list_entry(drv_data->queue.next, struct spi_message, queue);
++
++ list_del_init(&drv_data->cur_msg->queue);
++ drv_data->busy = 1;
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++
++ /* Initial message state */
++ drv_data->cur_msg->state = START_STATE;
++ drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
++ struct spi_transfer, transfer_list);
++
++ /* Setup the SPI using the per chip configuration */
++ drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
++ drv_data->execute_cmd(drv_data, RESTORE_STATE);
++ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++
++ if (drv_data->cur_chip->xfer_type == POLLING_TRANSFER)
++ do_polling_transfer(drv_data);
++ else if (drv_data->cur_chip->xfer_type == INTERRUPT_TRANSFER)
++ do_interrupt_transfer(drv_data);
++ else /* DMA_TRANSFER*/
++ do_dma_transfer(drv_data);
++}
++
++int init_queue(struct driver_data *drv_data)
++{
++ INIT_LIST_HEAD(&drv_data->queue);
++ spin_lock_init(&drv_data->lock);
++
++ drv_data->run = QUEUE_STOPPED;
++ drv_data->busy = 0;
++
++ tasklet_init(&drv_data->pump_transfers, pump_transfers,
++ (unsigned long)drv_data);
++ INIT_WORK(&drv_data->spi_work, pump_messages);
++#ifdef SPI_WORKQUEUE
++ drv_data->workqueue = create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id);
++ if (drv_data->workqueue == NULL)
++ return -EBUSY;
++#endif
++ return 0;
++}
++EXPORT_SYMBOL(init_queue);
++
++int start_queue(struct driver_data *drv_data)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&drv_data->lock, flags);
++ if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ return -EBUSY;
++ }
++ drv_data->run = QUEUE_RUNNING;
++ drv_data->cur_msg = NULL;
++ drv_data->cur_transfer = NULL;
++ drv_data->cur_chip = NULL;
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ /*queue_work(drv_data->workqueue, &drv_data->pump_messages);*/
++ /*schedule_work(&drv_data->spi_work);*/
++ return 0;
++}
++EXPORT_SYMBOL(start_queue);
++
++int stop_queue(struct driver_data *drv_data)
++{
++ unsigned long flags;
++ unsigned limit = 500;
++ int status = 0;
++
++ spin_lock_irqsave(&drv_data->lock, flags);
++
++ /* This is a bit lame, but is optimized for the common execution path.
++ * A wait_queue on the drv_data->busy could be used, but then the common
++ * execution path (pump_messages) would be required to call wake_up or
++ * friends on every SPI message. Do this instead */
++ drv_data->run = QUEUE_STOPPED;
++ while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ msleep(10);
++ spin_lock_irqsave(&drv_data->lock, flags);
++ }
++ if (!list_empty(&drv_data->queue) || drv_data->busy)
++ status = -EBUSY;
++
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++
++ return status;
++}
++EXPORT_SYMBOL(stop_queue);
++
++int destroy_queue(struct driver_data *drv_data)
++{
++ int status;
++ status = stop_queue(drv_data);
++ if (status != 0)
++ return status;
++#ifdef SPI_WORKQUEUE
++ destroy_workqueue(drv_data->workqueue);
++#endif
++ return 0;
++}
++EXPORT_SYMBOL(destroy_queue);
++
++/**
++ * nomadik_spi_transfer - transfer function registered to SPI master framework
++ * @spi: spi device which is requesting transfer
++ * @msg: spi message which is to handled is queued to driver queue
++ *
++ * This function is registered to the SPI framework for this SPI master
++ * controller. It will queue the spi_message in the queue of driver if
++ * the queue is not stopped and return.
++ */
++int nomadik_spi_transfer(struct spi_device *spi, struct spi_message *msg)
++{
++ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++ unsigned long flags;
++
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++ struct spi_master *master;
++ int status = 0;
++#endif
++
++ nmdk_dbg_ftrace();
++
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++ master = drv_data->master;
++ switch(master->bus_num) {
++ case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user != SPI_USER_MSP) {
++ status = -EINVAL;
++ printk("MSP0 already in use in %d mode", drv_data->flag_msp0->user);
++ }
++ break;
++ case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user != SPI_USER_MSP) {
++ status = -EINVAL;
++ printk("MSP1 already in use in %d mode", drv_data->flag_msp1->user);
++ }
++ break;
++ case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user != SPI_USER_MSP) {
++ status = -EINVAL;
++ printk("MSP2 already in use in %d mode", drv_data->flag_msp2->user);
++ }
++ break;
++ }
++ if(status)
++ return status;
++#endif
++ spin_lock_irqsave(&drv_data->lock, flags);
++
++
++ if (drv_data->run == QUEUE_STOPPED) {
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ return -ESHUTDOWN;
++ }
++ if(drv_data->dma_ongoing){
++ struct chip_data *chip;
++ chip = spi_get_ctldata(spi);
++ nmdk_dbg(":::: Current chip(%p), Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip, chip->chip_id);
++ nmdk_dbg(":::: Current chip Id (doing infinite DMA): %d -- Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip->chip_id, chip->chip_id);
++ if(drv_data->cur_chip->chip_id != chip->chip_id){
++ nmdk_dbg(":::: Chip_id are not same, Hence current DMA xfer not disabled \n");
++ }
++ else{
++ nmdk_dbg(":::: Chip_id are same. Disabling current infinite DMA xfer\n");
++
++ drv_data->dma_ongoing = 0;
++
++ if (drv_data->cur_chip->dma_info->tx_dmach != -1) {
++ free_dma(drv_data->cur_chip->dma_info->tx_dmach);
++ drv_data->cur_chip->dma_info->tx_dmach = -1;
++ }
++ if (drv_data->cur_chip->dma_info->rx_dmach != -1) {
++ free_dma(drv_data->cur_chip->dma_info->rx_dmach);
++ drv_data->cur_chip->dma_info->rx_dmach = -1;
++ }
++ drv_data->execute_cmd(drv_data, DISABLE_DMA);
++ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++ drv_data->cur_msg = NULL;
++ drv_data->cur_transfer = NULL;
++ drv_data->cur_chip = NULL;
++#ifdef SPI_WORKQUEUE
++ queue_work(drv_data->workqueue, &drv_data->spi_work);
++#else
++ schedule_work(&drv_data->spi_work);
++#endif
++ }
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ return 0;
++ }
++
++ nmdk_dbg(":::: Regular request (No infinite DMA ongoing)\n");
++
++ msg->actual_length = 0;
++ msg->status = -EINPROGRESS;
++ msg->state = START_STATE;
++
++ list_add_tail(&msg->queue, &drv_data->queue);
++ if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
++#ifdef SPI_WORKQUEUE
++ queue_work(drv_data->workqueue, &drv_data->spi_work);
++#else
++ schedule_work(&drv_data->spi_work);
++#endif
++
++ spin_unlock_irqrestore(&drv_data->lock, flags);
++ return 0;
++}
++EXPORT_SYMBOL(nomadik_spi_transfer);
++
++int calculate_effective_freq(int freq, t_ssp_clock_params * clk_freq)
++{
++ /*Lets calculate the frequency parameters */
++ uint32 cpsdvsr = 2;
++ uint32 scr = 0;
++ bool_t freq_found = FALSE;
++ uint32 max_tclk;
++ uint32 min_tclk;
++
++ nmdk_dbg_ftrace();
++
++ max_tclk = (NMDK_SSP_CLOCK_FREQ / (MIN_CPSDVR * (1 + MIN_SCR))); /* cpsdvscr = 2 & scr 0 */
++ min_tclk = (NMDK_SSP_CLOCK_FREQ / (MAX_CPSDVR * (1 + MAX_SCR))); /* cpsdvsr = 254 & scr = 255 */
++
++ if ((freq <= max_tclk) && (freq >= min_tclk)) {
++ while (cpsdvsr <= MAX_CPSDVR && !freq_found) {
++ while (scr <= MAX_SCR && !freq_found) {
++ if ((NMDK_SSP_CLOCK_FREQ /
++ (cpsdvsr * (1 + scr))) > freq)
++ scr += 1;
++ else {
++ /* This bool is made TRUE when effective frequency >= target frequency is found */
++ freq_found = TRUE;
++ if ((NMDK_SSP_CLOCK_FREQ /
++ (cpsdvsr * (1 + scr))) != freq) {
++ if (scr == MIN_SCR) {
++ cpsdvsr -= 2;
++ scr = MAX_SCR;
++ } else
++ scr -= 1;
++ }
++ }
++ }
++ if (!freq_found) {
++ cpsdvsr += 2;
++ scr = MIN_SCR;
++ }
++ }
++ if (cpsdvsr != 0) {
++ nmdk_dbg(":::: SSP Effective Frequency is %ld\n", (NMDK_SSP_CLOCK_FREQ / (cpsdvsr * (1 + scr))));
++ clk_freq->cpsdvsr = (uint8) (cpsdvsr & 0xFF);
++ clk_freq->scr = (uint8) (scr & 0xFF);
++ nmdk_dbg(":::: SSP cpsdvsr = %d, scr = %d\n",
++ clk_freq->cpsdvsr, clk_freq->scr);
++ }
++ } else {
++ /*User is asking for out of range Freq. */
++ nmdk_dbg(":::: setup - controller data is incorrect: Out of Range Frequency");
++ return -EINVAL;
++ }
++ return 0;
++}
++EXPORT_SYMBOL(calculate_effective_freq);
++
++/**
++ * process_dma_info - Processes the DMA info provided by client drivers
++ * @chip_info: chip info provided by client device
++ * @chip: Runtime state maintained by the spi controller for each spi device
++ *
++ * This function processes and stores DMA config provided by client driver
++ * into the runtime state maintained by the spi controller driver
++ */
++int process_dma_info(struct nmdk_spi_config_chip *chip_info,
++ struct chip_data *chip, void * data)
++{
++ struct driver_data *drv_data = (struct driver_data *)data;
++
++ /* default setup required for any SPI dma transfer*/
++ chip->dma_info->rx_dma_info.srcdevtype = drv_data->master_info->dma_srcdevtype;
++ chip->dma_info->rx_dma_info.config = 0;
++
++ chip->dma_info->tx_dma_info.destdevtype = drv_data->master_info->dma_destdevtype;
++ chip->dma_info->tx_dma_info.config = 0;
++
++ if (chip_info->dma_xfer_type == SPI_WITH_MEM) {
++ chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_MEM);
++ chip->dma_info->rx_dma_info.destdevtype = "mem";
++
++ chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++ chip->dma_info->tx_dma_info.srcdevtype = "mem";
++ if (chip_info->dma_config) {
++ chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++ chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++ if (chip_info->dma_config->tx_client_dmadev_config) {
++ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
++ }
++ if (chip_info->dma_config->rx_client_dmadev_config) {
++ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
++ }
++ if (chip_info->dma_config->tx_master_dmadev_config) {
++ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
++ }
++ if (chip_info->dma_config->rx_master_dmadev_config) {
++ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
++ }
++ }
++ } else { /*SPI_WITH_PERIPH*/
++ chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
++ chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
++ if (chip_info->dma_config) {
++ chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++ chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++ if (chip_info->dma_config->tx_client_dmadev_config) {
++ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
++ chip->dma_info->rx_dma_info.destdevtype = chip_info->dma_config->tx_client_dmadev_config->devtype;
++ }
++ if (chip_info->dma_config->rx_client_dmadev_config) {
++ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
++ chip->dma_info->tx_dma_info.srcdevtype = chip_info->dma_config->rx_client_dmadev_config->devtype;
++ }
++ if (chip_info->dma_config->tx_master_dmadev_config) {
++ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
++ }
++ if (chip_info->dma_config->rx_master_dmadev_config) {
++ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
++ }
++ } else return -EINVAL;
++ }
++
++ print_dma_info(chip_info->dma_xfer_type, chip);
++ return 0;
++}
++
++EXPORT_SYMBOL(process_dma_info);
++
++/**
++ * nomadik_spi_cleanup - cleanup function registered to SPI master framework
++ * @spi: spi device which is requesting cleanup
++ *
++ * This function is registered to the SPI framework for this SPI master
++ * controller. It will free the runtime state of chip.
++ */
++void nomadik_spi_cleanup(const struct spi_device *spi)
++{
++ struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
++ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++ struct spi_master *master;
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++ int status =0;
++#endif
++ nmdk_dbg_ftrace();
++
++ master = drv_data->master;
++
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++ switch(master->bus_num) {
++ case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user == SPI_USER_MSP) {
++ down(&drv_data->flag_msp0->lock);
++ drv_data->flag_msp0->user = SPI_NO_MSP_USER;
++ up(&drv_data->flag_msp0->lock);
++ nmdk_dbg("Flag cleanup for MSP0\n");
++ }
++ else {
++ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", (drv_data->flag_msp0->user));
++ status = -EFAULT;
++ }
++ break;
++ case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user == SPI_USER_MSP) {
++ down(&drv_data->flag_msp1->lock);
++ drv_data->flag_msp1->user = SPI_NO_MSP_USER;
++ up(&drv_data->flag_msp1->lock);
++ nmdk_dbg("Flag cleanup for MSP1\n");
++ }
++ else {
++ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
++ status = -EFAULT;
++ }
++ break;
++ case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user == SPI_USER_MSP) {
++ down(&drv_data->flag_msp2->lock);
++ drv_data->flag_msp2->user = SPI_NO_MSP_USER;
++ up(&drv_data->flag_msp2->lock);
++ nmdk_dbg("Flag cleanup for MSP2\n");
++ }
++ else {
++ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
++ status = -EFAULT;
++ }
++ break;
++ }
++ if(status)
++ return ;
++#endif
++ if((master->bus_num == MSP_0_CONTROLLER) ||(master->bus_num == MSP_1_CONTROLLER) || (master->bus_num == MSP_2_CONTROLLER)) {
++ nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
++ free_irq(drv_data->adev->irq[0], drv_data);
++ }
++ if (chip){
++ if(chip->dma_info) {
++ if (chip->dma_info->tx_dmach != -1) {
++ free_dma(chip->dma_info->tx_dmach);
++ chip->dma_info->tx_dmach = -1;
++ }
++ if (chip->dma_info->rx_dmach != -1) {
++ free_dma(chip->dma_info->rx_dmach);
++ chip->dma_info->rx_dmach = -1;
++ }
++ kfree(chip->dma_info);
++ }
++ kfree(chip);
++ }
++}
++EXPORT_SYMBOL(nomadik_spi_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Sachin Verma <sachin.verma@st.com> : Vaibhav Agarwal <vaibhav.agarwal@st.com");
++MODULE_DESCRIPTION("Nomadik SPI driver");
+--- linux-2.6.20.orig/drivers/usb/Kconfig
++++ linux-2.6.20/drivers/usb/Kconfig
+@@ -131,7 +131,9 @@ source "drivers/usb/misc/Kconfig"
+
+ source "drivers/usb/atm/Kconfig"
+
+ source "drivers/usb/gadget/Kconfig"
+
++source "drivers/usb/nomadik/Kconfig"
++
+ endmenu
+
+--- linux-2.6.20.orig/drivers/usb/Makefile
++++ linux-2.6.20/drivers/usb/Makefile
+@@ -65,8 +65,9 @@ obj-$(CONFIG_USB_PHIDGETSERVO) += misc/
+ obj-$(CONFIG_USB_RIO500) += misc/
+ obj-$(CONFIG_USB_SISUSBVGA) += misc/
+ obj-$(CONFIG_USB_TEST) += misc/
+ obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/
+ obj-$(CONFIG_USB_USS720) += misc/
++obj-y += nomadik/
+
+ obj-$(CONFIG_USB_ATM) += atm/
+ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
+--- linux-2.6.20.orig/drivers/usb/gadget/file_storage.c
++++ linux-2.6.20/drivers/usb/gadget/file_storage.c
+@@ -270,16 +270,15 @@ static const char shortname[] = DRIVER_N
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_AUTHOR("Alan Stern");
+ MODULE_LICENSE("Dual BSD/GPL");
+
+-/* Thanks to NetChip Technologies for donating this product ID.
+- *
+- * DO NOT REUSE THESE IDs with any other driver!! Ever!!
+- * Instead: allocate your own, using normal USB-IF procedures. */
+-#define DRIVER_VENDOR_ID 0x0525 // NetChip
+-#define DRIVER_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget
++/*
++ * Replaced with ST ID
++ */
++#define DRIVER_VENDOR_ID 0x0483 // ST ID
++#define DRIVER_PRODUCT_ID 0x8815 // 0xa4a5 Linux-USB File-backed Storage Gadget
+
+
+ /*
+ * This driver assumes self-powered hardware and has no way for users to
+ * trigger remote wakeup. It uses autoconfiguration to select endpoints
+@@ -371,11 +370,11 @@ static struct {
+
+ } mod_data = { // Default values
+ .transport_parm = "BBB",
+ .protocol_parm = "SCSI",
+ .removable = 0,
+- .can_stall = 1,
++ .can_stall = 0, /* for nhk15 */
+ .vendor = DRIVER_VENDOR_ID,
+ .product = DRIVER_PRODUCT_ID,
+ .release = 0xffff, // Use controller chip type
+ .buflen = 16384,
+ };
+@@ -3858,11 +3857,11 @@ static int __init fsg_bind(struct usb_ga
+
+ if ((rc = check_parameters(fsg)) != 0)
+ goto out;
+
+ if (mod_data.removable) { // Enable the store_xxx attributes
+- dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
++ dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0777; /*NHK15*/
+ dev_attr_ro.store = store_ro;
+ dev_attr_file.store = store_file;
+ }
+
+ /* Find out how many LUNs there should be */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/Kconfig
+@@ -0,0 +1,176 @@
++#
++# INVENTRA USB Host Controller Drivers
++#
++# $Revision: 1.13 $
++#
++config USB_INVENTRA_HCD
++ depends on USB
++ tristate 'Inventra HCD Controller Support'
++ help
++ Say Y here if you have the Inventra USB board on your system.
++
++ If you do not know what this is, please say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called musb-hcd (host controller) or
++ musb-gcd (gadget controller) or musb-icd (interface
++ controller when OTG is enabled).
++
++choice
++prompt "Controller Mode"
++depends on USB_INVENTRA_HCD
++default USB_INVENTRA_HCD_HOST
++
++config USB_INVENTRA_HCD_HOST
++ bool 'Host Mode'
++
++config USB_INVENTRA_HCD_GADGET_API
++ bool 'GADGET API'
++ help
++ Say Y here if you want support for GADGET API; the module will
++ be called musb-gcd.ko
++
++ You will need to select the Inventra Controller in the Gadget
++ subsection.
++
++ If you do not know what this is, please say N.
++
++config USB_INVENTRA_HCD_OTG
++ bool 'On The Go'
++ help
++ Say Y here if you want support for USB On The Go.
++
++ The module will be called musb-icd.ko
++
++ If you do not know what this is, please say N.
++
++#config USB_INVENTRA_HCD_GSTORAGE
++# bool 'Storage Demo'
++# help
++# Say Y here if you want the hcd driver compiled as
++# like a mass storage device.
++#
++# If you do not know what this is, please say N.
++
++config USB_INVENTRA_HCD_OTG_GSTORAGE
++ bool 'OTG Storage Demo'
++ help
++ Say Y here if you want the hcd driver compiled as
++ a mass storage device with OTG support.
++
++ If you do not know what this is, please say N.
++
++
++endchoice
++
++config USB_INVENTRA_STATIC_CONFIG
++ depends on USB_INVENTRA_HCD
++ bool 'Use static config (-DMUSB_STATIC_CONFIG)'
++ default true
++ help
++ Use the static configuration file. File must be called
++ hdrc_cnf.h and mut be generated from the board configuration
++ file. Please check directory install/configs for examples.
++
++ If usure please say please say N and make sure your controller
++ is using the standard configuration HB+8E(8K)+8DMA
++
++ NOTE: Make sure your board is using the corresponding core.
++
++config USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
++ depends on USB_INVENTRA_STATIC_CONFIG
++ string 'Endpoint FIFO configuration file (Advanced)'
++ default ''
++ help
++ Specify the file with the endpoint fifo configuration (Advanced). The
++ file shoud define an struct MUSB_EpFifoDescriptor array called
++ MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] containig the end point FIFO
++ configuration specs. Check musbdefs.h for more informations;
++
++ struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS]={
++
++ {}, /* EP0 use the default */
++ { MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
++ { MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 }
++
++ };
++
++ gives the endpoint 0 its default value, and defines ep1/ep2 as bulk tx/rx
++ 512 bytes in size each with double buffering disabled. The FIFO memory
++ allocated with this confoguration is 64+512+512=1088 bytes
++
++config USB_INVENTRA_DMA
++ depends on USB_INVENTRA_HCD
++ bool 'Use DMA when possible (-DMUSB_DMA)'
++ default true
++ help
++ Enable DMA transfers when DMA is possible
++
++config USB_INVENTRA_MUSB_HAS_AHB_ID
++ depends on USB_INVENTRA_HCD
++ bool 'Enable AHB_ID (-DMUSB_AHB_ID)'
++ default false
++ help
++ Disable auto core identification.
++
++ NOTE: Make sure your board is using the corresponding core.
++
++config USB_INVENTRA_MUSB_HDR_CCNF_FILE
++ depends on USB_INVENTRA_HCD
++ string 'Custom config file (Advanced)'
++ default ''
++ help
++ Specify a custom config file (Advanced)
++
++config USB_INVENTRA_MUSB_BOARD_FILE
++ depends on USB_INVENTRA_HCD
++ string 'Custom board file (Advanced)'
++ default ''
++ help
++ Specify a custom board file (Advanced)
++
++config USB_INVENTRA_TPL
++ depends on USB_INVENTRA_HCD_OTG
++ tristate ' Use TPL (-DMUSB_TPL)'
++ default false
++ help
++ Enable Target Peripheral List
++
++config USB_INVENTRA_PROC_TESTMUSB
++ depends on USB_INVENTRA_HCD && PROC_FS && ( USB_INVENTRA_HOSTMODE || USB_INVENTRA_OTG )
++ bool 'Enable /proc/testmusbhdrc*'
++ default false
++ help
++ Add /proc/testmusbhdrc<num> to control the
++
++ NOTE: this is different from supporting /proc filesystem;
++
++ If you do not know what this is, please say N.
++
++config USB_INVENTRA_HCD_CUSTOM_OPTIONS
++ depends on USB_INVENTRA_HCD
++ string 'Custom compile options (Advanced)'
++ default ''
++ help
++ Specify a custom compile options (Advanced)
++
++config USB_INVENTRA_HCD_POLLING
++ depends on USB_INVENTRA_HCD
++ bool 'Use polling driver (debug only)'
++ default false
++ help
++ Enable polling mode (events won't be triggered by IRQs); usefule
++ for debugging.
++
++ If you do not know what this is, please say N.
++
++config USB_INVENTRA_HCD_LOGGING
++ depends on USB_INVENTRA_HCD
++ int 'Logging Level (0 - none / 3 - annoying)'
++ default 0
++ help
++ Set the logging level. 0 disable the debugging altogether (no
++ code will be added to the)
++
++ If you do not know what this is, please say N.
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/Makefile
+@@ -0,0 +1,97 @@
++MUSB_VERSION=2.2.2
++HCD_TYPE=hcd
++
++
++obj-$(CONFIG_USB_INVENTRA_HCD) += musb-hcd.o
++
++
++
++ifeq ($(CONFIG_PROC_FS),y)
++ musb-$(HCD_TYPE)-objs += musb_procfs.o
++endif
++
++
++ifneq ($(CONFIG_USB_INVENTRA_MUSB_BOARD_FILE),"")
++ EXTRA_CFLAGS += -DMUSB_BOARD_FILE
++endif
++
++ifneq ($(CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE),"")
++EXTRA_CFLAGS += -DMUSB_HDR_CCNF_FILE
++endif
++
++ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
++ifneq ($(CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE),"")
++EXTRA_CFLAGS += -DMUSB_EPFIFOCONFIG_FILE
++endif
++endif
++
++ifneq ($(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS),"")
++EXTRA_CFLAGS += $(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS)
++endif
+
-+#include <linux/io.h>
+
-+#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
-+#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
-+#endif
-+#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
-+#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
-+#endif
-+#ifndef CONFIG_ONENAND_SIM_VERSION_ID
-+#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
-+#endif
++ EXTRA_CFLAGS += -DMUSB_C_DYNFIFO_DEF
++ EXTRA_CFLAGS += -DMUSB_EPDISCRIPTORS_FILE
+
-+static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER;
-+static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID;
-+static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
++ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
++ EXTRA_CFLAGS += -DMUSB_AHB_ID
++endif
+
-+struct onenand_flash {
-+ void __iomem *base;
-+ void __iomem *data;
-+};
++ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
++ EXTRA_CFLAGS += -DMUSB_DMA
++ musb-$(HCD_TYPE)-objs += musbhsdma.o
++endif
+
-+#define ONENAND_CORE(flash) (flash->data)
-+#define ONENAND_CORE_SPARE(flash, this, offset) \
-+ ((flash->data) + (this->chipsize) + (offset >> 5))
++EXTRA_CFLAGS += -DMUSB_VERSION='"$(MUSB_VERSION)"' -DHCD_NAME=$(HCD_NAME)
+
-+#define ONENAND_MAIN_AREA(this, offset) \
-+ (this->base + ONENAND_DATARAM + offset)
++ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
++ EXTRA_CFLAGS += -DMUSB_STATIC_CONFIG
++endif
+
-+#define ONENAND_SPARE_AREA(this, offset) \
-+ (this->base + ONENAND_SPARERAM + offset)
++ifeq ($(CONFIG_USB_INVENTRA_HCD_OTG),y)
++ GADGET_API=y
++ MUSB_HOSTMODE=y
++ EXTRA_CFLAGS += -DMUSB_OTG
++ musb-$(HCD_TYPE)-objs += otg.o
++endif
+
-+#define ONENAND_GET_WP_STATUS(this) \
-+ (readw(this->base + ONENAND_REG_WP_STATUS))
++ifeq ($(CONFIG_USB_INVENTRA_HCD_GADGET_API),y)
++ GADGET_API=y
++endif
+
-+#define ONENAND_SET_WP_STATUS(v, this) \
-+ (writew(v, this->base + ONENAND_REG_WP_STATUS))
++#ifneq ($(GADGET_API),)
+
-+/* It has all 0xff chars */
-+#define MAX_ONENAND_PAGESIZE (2048 + 64)
-+static unsigned char *ffchars;
++# GADGET_DIRS=y
++# EXTRA_CFLAGS += -DMUSB_GADGET
++# musb-$(HCD_TYPE)-objs += musb_gadgetcommon.o g_ep0.o musb_gadget.o
++#endif
+
-+static struct mtd_partition os_partitions[] = {
-+ {
-+ .name = "OneNAND simulator partition",
-+ .offset = 0,
-+ .size = MTDPART_SIZ_FULL,
-+ },
-+};
+
-+/*
-+ * OneNAND simulator mtd
-+ */
-+struct onenand_info {
-+ struct mtd_info mtd;
-+ struct mtd_partition *parts;
-+ struct onenand_chip onenand;
-+ struct onenand_flash flash;
-+};
++ifeq ($(CONFIG_USB_INVENTRA_HCD_HOST),y)
++ MUSB_HOSTMODE=y
++endif
+
-+static struct onenand_info *info;
+
-+#define DPRINTK(format, args...) \
-+do { \
-+ printk(KERN_DEBUG "%s[%d]: " format "\n", __func__, \
-+ __LINE__, ##args); \
-+} while (0)
++ifeq ($(MUSB_HOSTMODE),y)
++ EXTRA_CFLAGS += -DMUSB_HOST
++ musb-$(HCD_TYPE)-objs += musb_virthub.o musb_host.o musb-hcd.o musb_plat_uds.o musb_bus_direct.o musb_epfifocfg.o musb_ioctl.o nomadik_udc.o otg_pwm.o otg_func.o
+
-+/**
-+ * onenand_lock_handle - Handle Lock scheme
-+ * @this: OneNAND device structure
-+ * @cmd: The command to be sent
-+ *
-+ * Send lock command to OneNAND device.
-+ * The lock scheme depends on chip type.
-+ */
-+static void onenand_lock_handle(struct onenand_chip *this, int cmd)
-+{
-+ int block_lock_scheme;
-+ int status;
++endif
+
-+ status = ONENAND_GET_WP_STATUS(this);
-+ block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
++ifndef DEBUG
++ DEBUG=0
++endif
+
-+ switch (cmd) {
-+ case ONENAND_CMD_UNLOCK:
-+ if (block_lock_scheme)
-+ ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
-+ else
-+ ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
-+ break;
++MUSB_DEBUG=$(CONFIG_USB_INVENTRA_HCD_LOGGING)
++ifeq ("$(strip $(MUSB_DEBUG))","")
++ MUSB_DEBUG:=$(DEBUG)
++endif
+
-+ case ONENAND_CMD_LOCK:
-+ if (block_lock_scheme)
-+ ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
-+ else
-+ ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
-+ break;
+
-+ case ONENAND_CMD_LOCK_TIGHT:
-+ if (block_lock_scheme)
-+ ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
-+ else
-+ ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
-+ break;
++ifneq ($(MUSB_DEBUG),0)
++ EXTRA_CFLAGS += -g
++ musb-$(HCD_TYPE)-objs += musb_debug.o
++endif
+
-+ default:
-+ break;
-+ }
-+}
++EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
+
-+/**
-+ * onenand_bootram_handle - Handle BootRAM area
-+ * @this: OneNAND device structure
-+ * @cmd: The command to be sent
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/board.h
+@@ -0,0 +1,58 @@
++/*
++ * linux/drivers/usb/nomadik/board.h
+ *
-+ * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
-+static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
-+{
-+ switch (cmd) {
-+ case ONENAND_CMD_READID:
-+ writew(manuf_id, this->base);
-+ writew(device_id, this->base + 2);
-+ writew(version_id, this->base + 4);
-+ break;
+
-+ default:
-+ /* REVIST: Handle other commands */
-+ break;
-+ }
-+}
+
-+/**
-+ * onenand_update_interrupt - Set interrupt register
-+ * @this: OneNAND device structure
-+ * @cmd: The command to be sent
++/*
++ * Example board-specific definitions.
++ * $Revision: 1.6 $
+ *
-+ * Update interrupt register. The status depends on command.
++ * It is suggested to:
++ * 1. Copy this file to one named after your target:
++ * cp board.h board-mytarget.h
++ * 2. Save this file for future reference:
++ * mv board.h board-example.h
++ * 3. Link board.h to yours:
++ * ln -s board-mytarget.h board.h
++ * 4. Edit yours, providing, for each controller:
++ * - controller type (MUSB_CONTROLLER_HDRC or MUSB_CONTROLLER_MHDRC)
++ * - physical base address in kernel space
++ * - interrupt number (interpretation is platform-specific)
+ */
-+static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
-+{
-+ int interrupt = ONENAND_INT_MASTER;
-+
-+ switch (cmd) {
-+ case ONENAND_CMD_READ:
-+ case ONENAND_CMD_READOOB:
-+ interrupt |= ONENAND_INT_READ;
-+ break;
-+
-+ case ONENAND_CMD_PROG:
-+ case ONENAND_CMD_PROGOOB:
-+ interrupt |= ONENAND_INT_WRITE;
-+ break;
+
-+ case ONENAND_CMD_ERASE:
-+ interrupt |= ONENAND_INT_ERASE;
-+ break;
++/** Array of information about hard-wired controllers
++ * This will be liked to the first module that includes this file.
++ */
+
-+ case ONENAND_CMD_RESET:
-+ interrupt |= ONENAND_INT_RESET;
-+ break;
++#ifndef __MUSB_LINUX_BOARD_H__
++#define __MUSB_LINUX_BOARD_H__
++#include <asm/arch/soc_devices.h>
+
-+ default:
-+ break;
-+ }
++#include <asm/arch/irqs.h>
++#define INT_USBOTG IRQ_USBOTG
+
-+ writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
-+}
++MUSB_LinuxController MUSB_aLinuxController[] =
++{
++ { MUSB_CONTROLLER_HDRC, (void*)NOMADIK_USB_BASE, INT_USBOTG }
++ /*
++ { MUSB_CONTROLLER_HDRC, (void*)0xc0000000, 9 }
++ */
++};
+
-+/**
-+ * onenand_check_overwrite - Check if over-write happened
-+ * @dest: The destination pointer
-+ * @src: The source pointer
-+ * @count: The length to be check
++#endif /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/debug.h
+@@ -0,0 +1,104 @@
++/*
++ * linux/drivers/usb/nomadik/debug.h
+ *
-+ * Returns: 0 on same, otherwise 1
++ * Copyright 2007, STMicroelectronics
+ *
-+ * Compare the source with destination
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
-+static int onenand_check_overwrite(void *dest, void *src, size_t count)
-+{
-+ unsigned int *s = (unsigned int *) src;
-+ unsigned int *d = (unsigned int *) dest;
-+ int i;
-+
-+ count >>= 2;
-+ for (i = 0; i < count; i++)
-+ if ((*s++ ^ *d++) != 0)
-+ return 1;
+
-+ return 0;
-+}
++#ifndef __MUSB_LINUX_DEBUG_H__
++#define __MUSB_LINUX_DEBUG_H__
+
-+/**
-+ * onenand_data_handle - Handle OneNAND Core and DataRAM
-+ * @this: OneNAND device structure
-+ * @cmd: The command to be sent
-+ * @dataram: Which dataram used
-+ * @offset: The offset to OneNAND Core
++/*
++ * Linux HCD (Host Controller Driver) for HDRC and/or MHDRC.
++ * Debug support routines
+ *
-+ * Copy data from OneNAND Core to DataRAM (read)
-+ * Copy data from DataRAM to OneNAND Core (write)
-+ * Erase the OneNAND Core (erase)
+ */
-+static void onenand_data_handle(struct onenand_chip *this, int cmd,
-+ int dataram, unsigned int offset)
-+{
-+ struct mtd_info *mtd = &info->mtd;
-+ struct onenand_flash *flash = this->priv;
-+ int main_offset, spare_offset;
-+ void __iomem *src;
-+ void __iomem *dest;
-+ unsigned int i;
+
-+ if (dataram) {
-+ main_offset = mtd->writesize;
-+ spare_offset = mtd->oobsize;
-+ } else {
-+ main_offset = 0;
-+ spare_offset = 0;
-+ }
++#define MUSB_MONITOR_DATA
+
-+ switch (cmd) {
-+ case ONENAND_CMD_READ:
-+ src = ONENAND_CORE(flash) + offset;
-+ dest = ONENAND_MAIN_AREA(this, main_offset);
-+ memcpy(dest, src, mtd->writesize);
-+ /* Fall through */
++#define yprintk(facility, format, args...) do { printk(facility "%s %d: " format , \
++ __FUNCTION__, __LINE__ , ## args); } while (0)
++#define WARN(fmt, args...) yprintk(KERN_WARNING,fmt, ## args)
++#define INFO(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
++#define ERR(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
+
-+ case ONENAND_CMD_READOOB:
-+ src = ONENAND_CORE_SPARE(flash, this, offset);
-+ dest = ONENAND_SPARE_AREA(this, spare_offset);
-+ memcpy(dest, src, mtd->oobsize);
-+ break;
++#if MUSB_DEBUG > 0
+
-+ case ONENAND_CMD_PROG:
-+ src = ONENAND_MAIN_AREA(this, main_offset);
-+ dest = ONENAND_CORE(flash) + offset;
-+ /* To handle partial write */
-+ for (i = 0; i < (1 << mtd->subpage_sft); i++) {
-+ int off = i * this->subpagesize;
-+ if (!memcmp(src + off, ffchars, this->subpagesize))
-+ continue;
-+ if (memcmp(dest + off, ffchars, this->subpagesize) &&
-+ onenand_check_overwrite(dest + off, src + off, this->subpagesize))
-+ printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
-+ memcpy(dest + off, src + off, this->subpagesize);
-+ }
-+ /* Fall through */
++#define STATIC
++#define MGC_GetDebugLevel() (MGC_DebugLevel)
++#define MGC_EnableDebug() do { MGC_DebugDisable=0; } while(0)
++#define MGC_DisableDebug() do { MGC_DebugDisable=1; } while(0)
+
-+ case ONENAND_CMD_PROGOOB:
-+ src = ONENAND_SPARE_AREA(this, spare_offset);
-+ /* Check all data is 0xff chars */
-+ if (!memcmp(src, ffchars, mtd->oobsize))
-+ break;
++#define _dbg_level(level) ( !MGC_DebugDisable && ((level>=-1 && MGC_GetDebugLevel()>=level) || MGC_GetDebugLevel()==level) )
+
-+ dest = ONENAND_CORE_SPARE(flash, this, offset);
-+ if (memcmp(dest, ffchars, mtd->oobsize) &&
-+ onenand_check_overwrite(dest, src, mtd->oobsize))
-+ printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
-+ offset);
-+ memcpy(dest, src, mtd->oobsize);
-+ break;
++#define xprintk(level, facility, format, args...) do { if ( _dbg_level(level) ) { \
++ printk(facility "%s %d: " format , __FUNCTION__, __LINE__ , ## args); } } while (0)
+
-+ case ONENAND_CMD_ERASE:
-+ memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
-+ memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
-+ (mtd->erasesize >> 5));
-+ break;
++#define PARANOID( x ) do {} while (0)
++#define DBG(level,fmt,args...) xprintk(level,KERN_INFO,fmt, ## args)
++#define DEBUG_CODE(level, code) do { if ( _dbg_level(level) ) { code } } while (0)
++#define TRACE(n) DEBUG_CODE(n, printk(KERN_INFO "%s:%s:%d: trace\n", \
++ __FILE__, __FUNCTION__, __LINE__); )
+
-+ default:
-+ break;
-+ }
-+}
++#define ASSERT_SPINLOCK_LOCKED(_x)
++#define ASSERT_SPINLOCK_UNLOCKED(_x)
++/* #define ASSERT_SPINLOCK_LOCKED(_x) do { if (!spin_is_locked(_x)) \
++ ERR("@pre clause failed, _x must be locked\n"); } while (0)
++#define ASSERT_SPINLOCK_UNLOCKED(_x) do { if (spin_is_locked(_x)) \
++ ERR("@pre clause failed, _x must be unlocked\n"); } while (0) */
+
-+/**
-+ * onenand_command_handle - Handle command
-+ * @this: OneNAND device structure
-+ * @cmd: The command to be sent
-+ *
-+ * Emulate OneNAND command.
-+ */
-+static void onenand_command_handle(struct onenand_chip *this, int cmd)
-+{
-+ unsigned long offset = 0;
-+ int block = -1, page = -1, bufferram = -1;
-+ int dataram = 0;
++/* debug no defined */
+
-+ switch (cmd) {
-+ case ONENAND_CMD_UNLOCK:
-+ case ONENAND_CMD_LOCK:
-+ case ONENAND_CMD_LOCK_TIGHT:
-+ case ONENAND_CMD_UNLOCK_ALL:
-+ onenand_lock_handle(this, cmd);
-+ break;
++#else
+
-+ case ONENAND_CMD_BUFFERRAM:
-+ /* Do nothing */
-+ return;
++#define STATIC static
++#define MGC_GetDebugLevel() 0
++#define MGC_EnableDebug()
++#define MGC_DisableDebug()
+
-+ default:
-+ block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
-+ if (block & (1 << ONENAND_DDP_SHIFT)) {
-+ block &= ~(1 << ONENAND_DDP_SHIFT);
-+ /* The half of chip block */
-+ block += this->chipsize >> (this->erase_shift + 1);
-+ }
-+ if (cmd == ONENAND_CMD_ERASE)
-+ break;
++#define PARANOID( x ) do {} while (0)
++#define DBG(fmt,args...) do {} while (0)
++#define DEBUG_CODE(x, y) do {} while (0)
++#define TRACE(n) do {} while (0)
+
-+ page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
-+ page = (page >> ONENAND_FPA_SHIFT);
-+ bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
-+ bufferram >>= ONENAND_BSA_SHIFT;
-+ bufferram &= ONENAND_BSA_DATARAM1;
-+ dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
-+ break;
-+ }
++#define ASSERT_SPINLOCK_LOCKED(_x)
++#define ASSERT_SPINLOCK_UNLOCKED(_x)
+
-+ if (block != -1)
-+ offset += block << this->erase_shift;
++#endif
+
-+ if (page != -1)
-+ offset += page << this->page_shift;
++/*----------------------- DEBUG function/macros -----------------------------*/
+
-+ onenand_data_handle(this, cmd, dataram, offset);
++#if MUSB_DEBUG > 0
++struct usb_ep;
++struct list_head;
++struct usb_request;
++struct usb_ctrlrequest;
+
-+ onenand_update_interrupt(this, cmd);
-+}
++extern int MGC_DebugLevel;
++extern int MGC_DebugDisable;
+
-+/**
-+ * onenand_writew - [OneNAND Interface] Emulate write operation
-+ * @value: value to write
-+ * @addr: address to write
++extern void dump_urb(void *urb);
++extern char *decode_csr0(uint16_t csr0);
++extern char *decode_txcsr(uint16_t txcsr);
++extern char *decode_devctl(uint16_t devclt);
++extern char *decode_ep0stage(uint8_t stage);
++extern char *dump_node(struct list_head *node);
++extern char *decode_usb_ctrlrequest(const struct usb_ctrlrequest *pControlRequest);
++extern char *decode_request(struct usb_ctrlrequest*) ;
++extern void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd);
++#endif
++
++#endif // __MUSB_LINUX_DEBUG_H__
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/dma.h
+@@ -0,0 +1,308 @@
++/*
++ * linux/drivers/usb/nomadik/dma.h
+ *
-+ * Write OneNAND register with value
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
-+static void onenand_writew(unsigned short value, void __iomem * addr)
-+{
-+ struct onenand_chip *this = info->mtd.priv;
+
-+ /* BootRAM handling */
-+ if (addr < this->base + ONENAND_DATARAM) {
-+ onenand_bootram_handle(this, value);
-+ return;
-+ }
-+ /* Command handling */
-+ if (addr == this->base + ONENAND_REG_COMMAND)
-+ onenand_command_handle(this, value);
++#ifndef __MUSB_DMA_H__
++#define __MUSB_DMA_H__
+
-+ writew(value, addr);
-+}
++/**
++ * Introduction.
++ * The purpose of the DMA Controller Abstraction (DCA) is to allow the ICD
++ * to use any DMA controller,
++ * since this is an option in the Inventra USB cores.
++ * The assumptions are:
++ * <ul>
++ * <li>A DMA controller will be tied to an Inventra USB core in the
++ * way specified in the Inventra core product specification.
++ * <li>A DMA controller's base address in the memory map correlates
++ * somehow to the Inventra USB core it serves.
++ * </ul>
++ * The responsibilities of an implementation include:
++ * <ul>
++ * <li>Allocating/releasing buffers for use with DMA
++ * (this may be specific to a DMA controller, intervening busses,
++ * and a target's capabilities,
++ * so the ICD cannot make assumptions or provide services here)
++ * <li>Handling the details of moving multiple USB packets
++ * in cooperation with the Inventra USB core.
++ * <li>Knowing the correlation between channels and the
++ * Inventra core's local endpoint resources and data direction,
++ * and maintaining a list of allocated/available channels.
++ * <li>Updating channel status on interrupts,
++ * whether shared with the Inventra core or separate.
++ * <li>If the DMA interrupt is shared with the Inventra core,
++ * handling it when called, and reporting whether it was the
++ * source of interrupt.
++ * </ul>
++ */
++
++/*************************** CONSTANTS ****************************/
+
+/**
-+ * flash_init - Initialize OneNAND simulator
-+ * @flash: OneNAND simulator data strucutres
-+ *
-+ * Initialize OneNAND simulator.
++ * DMA channel status.
+ */
-+static int __init flash_init(struct onenand_flash *flash)
++typedef enum
+{
-+ int density, size;
-+ int buffer_size;
++ /** A channel's status is unknown */
++ MGC_DMA_STATUS_UNKNOWN,
++ /** A channel is available (not busy and no errors) */
++ MGC_DMA_STATUS_FREE,
++ /** A channel is busy (not finished attempting its transactions) */
++ MGC_DMA_STATUS_BUSY,
++ /** A channel aborted its transactions due to a local bus error */
++ MGC_DMA_STATUS_BUS_ABORT,
++ /** A channel aborted its transactions due to a core error */
++ MGC_DMA_STATUS_CORE_ABORT
++} MGC_DmaChannelStatus;
+
-+ flash->base = kzalloc(131072, GFP_KERNEL);
-+ if (!flash->base) {
-+ printk(KERN_ERR "Unable to allocate base address.\n");
-+ return -ENOMEM;
-+ }
++/***************************** TYPES ******************************/
+
-+ density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
-+ size = ((16 << 20) << density);
++/**
++ * MGC_DmaChannel.
++ * A DMA channel.
++ * @field pPrivateData channel-private data; not to be interpreted by the ICD
++ * @field wMaxLength the maximum number of bytes the channel can move
++ * in one transaction (typically representing many USB maximum-sized packets)
++ * @field dwActualLength how many bytes have been transferred
++ * @field bStatus current channel status (updated e.g. on interrupt)
++ * @field bDesiredMode TRUE if mode 1 is desired; FALSE if mode 0 is desired
++ */
++typedef struct
++{
++ void* pPrivateData;
++ uint32_t dwMaxLength;
++ uint32_t dwActualLength;
++ MGC_DmaChannelStatus bStatus;
++ uint8_t bDesiredMode;
++} MGC_DmaChannel;
+
-+ ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
-+ if (!ONENAND_CORE(flash)) {
-+ printk(KERN_ERR "Unable to allocate nand core address.\n");
-+ kfree(flash->base);
-+ return -ENOMEM;
-+ }
++/**
++ * Start a DMA controller.
++ * @param pPrivateData private data pointer from MGC_DmaController
++ * @return TRUE on success
++ * @return FALSE on failure (e.g. no DMAC appears present)
++ */
++typedef uint8_t (*MGC_pfDmaStartController)(void* pPrivateData);
+
-+ memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
++/**
++ * Stop a DMA controller.
++ * @param pPrivateData the controller's private data pointer
++ * @return TRUE on success
++ * @return FALSE on failure; the ICD may try again
++ */
++typedef uint8_t (*MGC_pfDmaStopController)(void* pPrivateData);
+
-+ /* Setup registers */
-+ writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
-+ writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
-+ writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
++/**
++ * Allocate a DMA channel.
++ * Allocate a DMA channel suitable for the given conditions.
++ * @param pPrivateData the controller's private data pointer
++ * @param bLocalEnd the local endpoint index (1-15)
++ * @param bTransmit TRUE for transmit; FALSE for receive
++ * @param bProtocol the USB protocol, as per USB 2.0 chapter 9
++ * (0 => control, 1 => isochronous, 2 => bulk, 3 => interrupt)
++ * @param wMaxPacketSize maximum packet size
++ * @return a non-NULL pointer on success
++ * @return NULL on failure (no channel available)
++ */
++typedef MGC_DmaChannel* (*MGC_pfDmaAllocateChannel)(
++ void* pPrivateData, uint8_t bLocalEnd,
++ uint8_t bTransmit, uint8_t bProtocol, uint16_t wMaxPacketSize);
+
-+ if (density < 2)
-+ buffer_size = 0x0400; /* 1KiB page */
-+ else
-+ buffer_size = 0x0800; /* 2KiB page */
-+ writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
++/**
++ * Release a DMA channel.
++ * Release a previously-allocated DMA channel.
++ * The ICD guarantess to no longer reference this channel.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ */
++typedef void (*MGC_pfDmaReleaseChannel)(MGC_DmaChannel* pChannel);
+
-+ return 0;
-+}
++/**
++ * Allocate DMA buffer.
++ * Allocate a buffer suitable for DMA operations with the given channel.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ * @param dwLength length, in bytes, desired for the buffer
++ * @return a non-NULL pointer to a suitable region (in processor space)
++ * on success
++ * @return NULL on failure
++ */
++typedef uint8_t* (*MGC_pfDmaAllocateBuffer)(MGC_DmaChannel* pChannel,
++ uint32_t dwLength);
+
+/**
-+ * flash_exit - Clean up OneNAND simulator
-+ * @flash: OneNAND simulator data structures
-+ *
-+ * Clean up OneNAND simulator.
++ * Release DMA buffer.
++ * Release a DMA buffer previously acquiring by a successful call
++ * to pController->pfDmaAllocateBuffer.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ * @param pBuffer the buffer pointer
++ * @return TRUE on success
++ * @return FALSE on failure (e.g. the controller owns the buffer at present)
+ */
-+static void flash_exit(struct onenand_flash *flash)
-+{
-+ vfree(ONENAND_CORE(flash));
-+ kfree(flash->base);
-+}
++typedef uint8_t (*MGC_pfDmaReleaseBuffer)(MGC_DmaChannel* pChannel,
++ uint8_t* pBuffer);
+
-+static int __init onenand_sim_init(void)
++/**
++ * Program a DMA channel.
++ * Program a DMA channel to move data at the core's request.
++ * The local core endpoint and direction should already be known,
++ * since they are specified in the pfDmaAllocateChannel call.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ * @param wPacketSize the packet size
++ * @param bMode TRUE if mode 1; FALSE if mode 0
++ * @param pBuffer base address of data (in processor space)
++ * @param dwLength the number of bytes to transfer;
++ * guaranteed by the ICD to be no larger than the channel's reported dwMaxLength
++ * @return TRUE on success
++ * @return FALSE on error
++ */
++typedef uint8_t (*MGC_pfDmaProgramChannel)(MGC_DmaChannel* pChannel,
++ uint16_t wPacketSize, uint8_t bMode,
++ const uint8_t* pBuffer,
++ uint32_t dwLength);
++
++/**
++ * Get DMA channel status.
++ * Get the current status of a DMA channel, if the hardware allows.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->DmaAllocateChannel
++ * @return current status
++ * (MGC_DMA_STATUS_UNKNOWN if hardware does not have readable status)
++ */
++typedef MGC_DmaChannelStatus (*MGC_pfDmaGetChannelStatus)(
++ MGC_DmaChannel* pChannel);
++
++/**
++ * DMA ISR.
++ * If present, this function is called by the ICD on every interrupt.
++ * This is necessary because with the built-in DMA controller
++ * (and probably some other configurations),
++ * the DMA interrupt is shared with other core interrupts.
++ * Therefore, this function should return quickly
++ * when there is no DMA interrupt.
++ * When there is a DMA interrupt, this function should
++ * perform any implementations-specific operations,
++ * and update the status of all appropriate channels.
++ * If the DMA controller has its own dedicated interrupt,
++ * this function should do nothing.
++ * This function is called BEFORE the ICD handles other interrupts.
++ * @param pPrivateData the controller's private data pointer
++ * @return TRUE if an interrupt was serviced
++ * @return FALSE if no interrupt required servicing
++ */
++typedef uint8_t (*MGC_pfDmaControllerIsr)(void* pPrivateData);
++
++/**
++ * MGC_DmaController.
++ * A DMA Controller.
++ * This is in a struct to allow the ICD to support
++ * multiple cores of different types,
++ * since each may use a different type of DMA controller.
++ * @field pPrivateData controller-private data;
++ * not to be interpreted by the ICD
++ * @field pfDmaStartController ICD calls this to start a DMA controller
++ * @field pfDmaStopController ICD calls this to stop a DMA controller
++ * @field pfDmaAllocateChannel ICD calls this to allocate a DMA channel
++ * @field pfDmaReleaseChannel ICD calls this to release a DMA channel
++ * @field pfDmaAllocateBuffer ICD calls this to allocate a DMA buffer
++ * @field pfDmaReleaseBuffer ICD calls this to release a DMA buffer
++ * @field pfDmaGetChannelStatus ICD calls this to get a DMA channel's status
++ * @field pfDmaControllerIsr ICD calls this (if non-NULL) from its ISR
++ */
++typedef struct
+{
-+ /* Allocate all 0xff chars pointer */
-+ ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
-+ if (!ffchars) {
-+ printk(KERN_ERR "Unable to allocate ff chars.\n");
-+ return -ENOMEM;
-+ }
-+ memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
++ void* pPrivateData;
++ MGC_pfDmaStartController pfDmaStartController;
++ MGC_pfDmaStopController pfDmaStopController;
++ MGC_pfDmaAllocateChannel pfDmaAllocateChannel;
++ MGC_pfDmaReleaseChannel pfDmaReleaseChannel;
++ MGC_pfDmaAllocateBuffer pfDmaAllocateBuffer;
++ MGC_pfDmaReleaseBuffer pfDmaReleaseBuffer;
++ MGC_pfDmaProgramChannel pfDmaProgramChannel;
++ MGC_pfDmaGetChannelStatus pfDmaGetChannelStatus;
++ MGC_pfDmaControllerIsr pfDmaControllerIsr;
++} MGC_DmaController;
+
-+ /* Allocate OneNAND simulator mtd pointer */
-+ info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
-+ if (!info) {
-+ printk(KERN_ERR "Unable to allocate core structures.\n");
-+ kfree(ffchars);
-+ return -ENOMEM;
-+ }
++/**
++ * A DMA channel has new status.
++ * This may be used to notify the ICD of channel status changes asynchronously.
++ * This is useful if the DMA interrupt is different from the USB controller's
++ * interrupt, so on some systems there may be no control over the order of
++ * USB controller and DMA controller assertion.
++ * @param pPrivateData the controller's private data pointer
++ * @param bLocalEnd the local endpoint index (1-15)
++ * @param bTransmit TRUE for transmit; FALSE for receive
++ * @return TRUE if an IRP was completed as a result of this call;
++ * FALSE otherwise
++ */
++typedef uint8_t (*MGC_pfDmaChannelStatusChanged)(
++ void* pPrivateData, uint8_t bLocalEnd,
++ uint8_t bTransmit);
+
-+ /* Override write_word function */
-+ info->onenand.write_word = onenand_writew;
++/**
++ * Instantiate a DMA controller.
++ * Instantiate a software object representing a DMA controller.
++ * @param pfDmaChannelStatusChanged channel status change notification function.
++ * Normally, the ICD requests status in its interrupt handler.
++ * For some DMA controllers, this may not be the correct time.
++ * @param pDmaPrivate parameter for pfDmaChannelStatusChanged
++ * @param pCoreBase the base address (in kernel space) of the core
++ * It is assumed the DMA controller's registers' base address will be related
++ * to this in some way.
++ * @return non-NULL pointer on success
++ * @return NULL on failure (out of memory or exhausted
++ * a fixed number of controllers)
++ */
++typedef MGC_DmaController* (*MGC_pfNewDmaController)(
++ MGC_pfDmaChannelStatusChanged pfDmaChannelStatusChanged,
++ void* pDmaPrivate,
++ uint8_t* pCoreBase);
+
-+ if (flash_init(&info->flash)) {
-+ printk(KERN_ERR "Unable to allocate flash.\n");
-+ kfree(ffchars);
-+ kfree(info);
-+ return -ENOMEM;
-+ }
++/**
++ * Destroy DMA controller.
++ * Destroy a previously-instantiated DMA controller.
++ */
++typedef void (*MGC_pfDestroyDmaController)(
++ MGC_DmaController* pController);
+
-+ info->parts = os_partitions;
++/**
++ * MGC_DmaControllerFactory.
++ * A DMA controller factory.
++ * To allow for multi-core implementations and different
++ * types of cores and DMA controllers to co-exist,
++ * it is necessary to create them from factories.
++ * @field wCoreRegistersExtent the total size of the core's
++ * register region with the DMA controller present,
++ * for use in mapping the core into system memory.
++ * For example, the MHDRC core takes 0x200 bytes of address space.
++ * If your DMA controller starts at 0x200 and takes 0x100 bytes,
++ * set this to 0x300.
++ * @field pfNewDmaController create a DMA controller
++ * @field pfDestroyDmaController destroy a DMA controller
++ */
++typedef struct
++{
++ uint16_t wCoreRegistersExtent;
++ MGC_pfNewDmaController pfNewDmaController;
++ MGC_pfDestroyDmaController pfDestroyDmaController;
++} MGC_DmaControllerFactory;
+
-+ info->onenand.base = info->flash.base;
-+ info->onenand.priv = &info->flash;
++#endif /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/g_ep0.c
+@@ -0,0 +1,858 @@
++/*
++ * linux/drivers/usb/nomadik/g_ep0.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
+
-+ info->mtd.name = "OneNAND simulator";
-+ info->mtd.priv = &info->onenand;
-+ info->mtd.owner = THIS_MODULE;
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++#include <linux/spinlock.h>
+
-+ if (onenand_scan(&info->mtd, 1)) {
-+ flash_exit(&info->flash);
-+ kfree(ffchars);
-+ kfree(info);
-+ return -ENXIO;
-+ }
++#if defined(MUSB_V24) && !defined(MUSB_LINUX_MV21)
++/* dealing with Linux headers */
++struct usb_tt {
++ struct usb_device *hub; /* upstream highspeed hub */
++ int multi; /* true means one TT per port */
++};
++#include "hcd.h"
++#endif
+
-+ add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
++#include <linux/init.h>
++#include <linux/usb_ch9.h>
++#include "musbdefs.h"
++#include "musb_gadgetdefs.h"
+
-+ return 0;
++
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Identifies a transmit request.
++ * @param pControlRequest the control request
++ * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE,
++ * USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME
++ */
++uint8_t is_tx_request(const struct usb_ctrlrequest *pControlRequest)
++{
++ return ( pControlRequest->bRequestType & USB_DIR_IN );
+}
+
-+static void __exit onenand_sim_exit(void)
++/**
++ * Identifies a zero data request.
++ * @param pControlRequest the control request
++ * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
++ * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
++ *
++ */
++uint8_t is_zerodata_request(const struct usb_ctrlrequest *pControlRequest)
+{
-+ struct onenand_chip *this = info->mtd.priv;
-+ struct onenand_flash *flash = this->priv;
++ return ( 0==pControlRequest->wLength ) && !is_tx_request(pControlRequest);
++}
+
-+ onenand_release(&info->mtd);
-+ flash_exit(flash);
-+ kfree(ffchars);
-+ kfree(info);
++/**
++ * Identifies a receive request.
++ * @param pControlRequest the control request
++ * @return true for USB_REQ_SET_DESCRIPTOR
++ */
++uint8_t is_rx_request(const struct usb_ctrlrequest *pControlRequest)
++{
++ return pControlRequest->bRequest==USB_REQ_SET_DESCRIPTOR;
+}
+
-+module_init(onenand_sim_init);
-+module_exit(onenand_sim_exit);
++/* ---------------------------------------------------------------------- */
+
-+MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
-+MODULE_DESCRIPTION("The OneNAND flash simulator");
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/net/kgdboe.c ../new/linux-2.6.20/drivers/net/kgdboe.c
---- linux-2.6.20/drivers/net/kgdboe.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/kgdboe.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,294 @@
-+/*
-+ * drivers/net/kgdboe.c
-+ *
-+ * A network interface for GDB.
-+ * Based upon 'gdbserial' by David Grothe <dave@gcom.com>
-+ * and Scott Foehner <sfoehner@engr.sgi.com>
-+ *
-+ * Maintainers: Amit S. Kale <amitkale@linsyssoft.com> and
-+ * Tom Rini <trini@kernel.crashing.org>
++/**
++ * Forward a request to the driver.
+ *
-+ * 2004 (c) Amit S. Kale <amitkale@linsyssoft.com>
-+ * 2004-2005 (c) MontaVista Software, Inc.
-+ * 2005 (c) Wind River Systems, Inc.
++ * FROM: usb_gadget.h
++ * Accordingly, the driver's setup() callback must always implement all
++ * get_descriptor requests, returning at least a device descriptor and
++ * a configuration descriptor. Drivers must make sure the endpoint
++ * descriptors match any hardware constraints. Some hardware also constrains
++ * other descriptors. (The pxa250 allows only configurations 1, 2, or 3).
+ *
-+ * Contributors at various stages not listed above:
-+ * San Mehat <nettwerk@biodome.org>, Robert Walsh <rjwalsh@durables.org>,
-+ * wangdi <wangdi@clusterfs.com>, Matt Mackall <mpm@selenic.com>,
-+ * Pavel Machek <pavel@suse.cz>, Jason Wessel <jason.wessel@windriver.com>
++ * The driver's setup() callback must also implement set_configuration,
++ * and should also implement set_interface, get_configuration, and
++ * get_interface. Setting a configuration (or interface) is where
++ * endpoints should be activated or (config 0) shut down.
+ *
-+ * This file is licensed under the terms of the GNU General Public License
-+ * version 2. This program is licensed "as is" without any warranty of any
-+ * kind, whether express or implied.
++ * @param pControlRequest the usb control request to forward to the driver
+ */
++static int forward_to_driver(const struct usb_ctrlrequest *pControlRequest)
++{
++ int handled=-EOPNOTSUPP;
++ MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
+
-+#include <linux/kernel.h>
-+#include <linux/interrupt.h>
-+#include <linux/string.h>
-+#include <linux/kgdb.h>
-+#include <linux/netpoll.h>
-+#include <linux/init.h>
+
-+#include <asm/atomic.h>
++ DBG(2, "<== pThis->pGadgetDriver=%p, pControlRequest=%p\n",
++ pThis->pGadgetDriver, pControlRequest);
+
-+#define IN_BUF_SIZE 512 /* power of 2, please */
-+#define NOT_CONFIGURED_STRING "not_configured"
-+#define OUT_BUF_SIZE 30 /* We don't want to send too big of a packet. */
-+#define MAX_KGDBOE_CONFIG_STR 256
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
+
-+static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE];
-+static int in_head, in_tail, out_count;
-+static atomic_t in_count;
-+/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */
-+static int configured;
-+static struct kgdb_io local_kgdb_io_ops;
-+static int use_dynamic_mac;
++ if ( pThis->pGadgetDriver ){
++ handled=pThis->pGadgetDriver->setup(pThis->pGadget,
++ pControlRequest);
++ }
++ else{
++ printk("Error case\n");
++ }
+
-+MODULE_DESCRIPTION("KGDB driver for network interfaces");
-+MODULE_LICENSE("GPL");
-+static char config[MAX_KGDBOE_CONFIG_STR] = NOT_CONFIGURED_STRING;
-+static struct kparam_string kps = {
-+ .string = config,
-+ .maxlen = MAX_KGDBOE_CONFIG_STR,
-+};
++ DBG(2, "==> handled=%d\n", handled);
++ return handled;
++}
+
-+static void rx_hook(struct netpoll *np, int port, char *msg, int len,
-+ struct sk_buff *skb)
-+{
-+ int i;
++/* ---------------------------------------------------------------------- */
+
-+ np->remote_port = port;
++/**
++ * Service a receive request. Currently forward to the driver.
++ * @param pControlRequest the usb control request to service.
++ * @see is_rx_request
++ */
++static int service_rx_request(struct usb_ctrlrequest *pControlRequest)
++{
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
++ return forward_to_driver(pControlRequest);
++}
+
-+ /* Copy the MAC address if we need to. */
-+ if (use_dynamic_mac) {
-+ memcpy(np->remote_mac, eth_hdr(skb)->h_source,
-+ sizeof(np->remote_mac));
-+ use_dynamic_mac = 0;
-+ }
++/**
++ * Service a transmit request.
++ * @param pControlRequest the request to service
++ * @see is_tx_request
++ */
++void service_tx_status_request(const struct usb_ctrlrequest *pControlRequest)
++{
++ uint8_t handled=1;
++ uint8_t bResult[2], bEnd=0;
++ MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++ const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK;
+
-+ /*
-+ * This could be GDB trying to attach. But it could also be GDB
-+ * finishing up a session, with kgdb_connected=0 but GDB sending
-+ * an ACK for the final packet. To make sure we don't try and
-+ * make a breakpoint when GDB is leaving, make sure that if
-+ * !kgdb_connected the only len == 1 packet we allow is ^C.
-+ */
-+ if (!kgdb_connected && (len != 1 || msg[0] == 3) &&
-+ !atomic_read(&kgdb_setting_breakpoint)) {
-+ tasklet_schedule(&kgdb_tasklet_breakpoint);
-+ }
++ /* ack the request */
++ DBG(3, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY);
++ spin_unlock(&pThis->Lock);
+
-+ for (i = 0; i < len; i++) {
-+ if (msg[i] == 3)
-+ tasklet_schedule(&kgdb_tasklet_breakpoint);
++ switch (bRecip) {
+
-+ if (atomic_read(&in_count) >= IN_BUF_SIZE) {
-+ /* buffer overflow, clear it */
-+ in_head = in_tail = 0;
-+ atomic_set(&in_count, 0);
-+ break;
-+ }
-+ in_buf[in_head++] = msg[i];
-+ in_head &= (IN_BUF_SIZE - 1);
-+ atomic_inc(&in_count);
-+ }
-+}
++ case USB_RECIP_DEVICE:
++ DBG(3, "USB_RECIP_DEVICE()\n");
++ bResult[0] = pThis->bIsSelfPowered ? 1 : 0;
++ bResult[0] |= 2;
++ bResult[1] = 0;
++ MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult);
++ break;
+
-+static struct netpoll np = {
-+ .dev_name = "eth0",
-+ .name = "kgdboe",
-+ .rx_hook = rx_hook,
-+ .local_port = 6443,
-+ .remote_port = 6442,
-+ .remote_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
-+};
++ case USB_RECIP_ENDPOINT:
++ {
++ uint16_t wTest;
+
-+static void eth_pre_exception_handler(void)
-+{
-+ /* Increment the module count when the debugger is active */
-+ if (!kgdb_connected)
-+ try_module_get(THIS_MODULE);
-+ netpoll_set_trap(1);
-+}
++ DBG(3, "USB_RECIP_ENDPOINT()\n");
+
-+static void eth_post_exception_handler(void)
-+{
-+ /* decrement the module count when the debugger detaches */
-+ if (!kgdb_connected)
-+ module_put(THIS_MODULE);
-+ netpoll_set_trap(0);
-+}
++ bEnd = (uint8_t)pControlRequest->wIndex;
+
-+static int eth_get_char(void)
-+{
-+ int chr;
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, bEnd);
++ wTest = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++ MGC_SelectEnd(pBase, 0);
++ bResult[0] = (wTest & MGC_M_TXCSR_P_SENDSTALL) ? 1 : 0;
++ bResult[1] = 0;
++ MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult);
++ spin_unlock(&pThis->Lock);
++ }
++ break;
+
-+ while (atomic_read(&in_count) == 0)
-+ netpoll_poll(&np);
++ default:
++ handled=0;
++ break;
++ }
+
-+ chr = in_buf[in_tail++];
-+ in_tail &= (IN_BUF_SIZE - 1);
-+ atomic_dec(&in_count);
-+ return chr;
-+}
++ /* send it out! (this will trigger the ep0 completition IRQ)
++ * serviced in interrupt_complete() */
++ if ( handled ) {
++ pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT;
+
-+static void eth_flush_buf(void)
-+{
-+ if (out_count && np.dev) {
-+ netpoll_send_udp(&np, out_buf, out_count);
-+ memset(out_buf, 0, sizeof(out_buf));
-+ out_count = 0;
-+ }
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, bEnd);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_P_DATAEND);
++ spin_unlock(&pThis->Lock);
++ }
+}
+
-+static void eth_put_char(u8 chr)
++/**
++ * Service a transmit a request. End0 buffer contains the current
++ * request (a standard control request). Assumes the fifo to be at least
++ * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION,
++ * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS,
++ * USB_REQ_SYNC_FRAME.
++ *
++ * @param pControlRequest the request to service
++ * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not
++ * supprorted), > 0 when the request is processed
++ * @see is_tx_request
++ */
++static int service_tx_request(const struct usb_ctrlrequest *pControlRequest)
+{
-+ out_buf[out_count++] = chr;
-+ if (out_count == OUT_BUF_SIZE)
-+ eth_flush_buf();
-+}
++ int handled=0; /* not handled */
+
-+static int option_setup(char *opt)
-+{
-+ char opt_scratch[MAX_KGDBOE_CONFIG_STR];
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
+
-+ /* If we're being given a new configuration, copy it in. */
-+ if (opt != config)
-+ strcpy(config, opt);
-+ /* But work on a copy as netpoll_parse_options will eat it. */
-+ strcpy(opt_scratch, opt);
-+ configured = !netpoll_parse_options(&np, opt_scratch);
++ if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) {
++ return forward_to_driver(pControlRequest);
++ }
+
-+ use_dynamic_mac = 1;
++ switch (pControlRequest->bRequest) {
++ case USB_REQ_GET_CONFIGURATION:
++ DBG(3, "USB_REQ_GET_CONFIGURATION()\n");
++ break;
+
-+ return 0;
-+}
-+__setup("kgdboe=", option_setup);
++ case USB_REQ_GET_INTERFACE:
++ DBG(3, "USB_REQ_GET_INTERFACE()\n");
++ break;
+
-+/* With our config string set by some means, configure kgdboe. */
-+static int configure_kgdboe(void)
-+{
-+ /* Try out the string. */
-+ option_setup(config);
++ case USB_REQ_GET_DESCRIPTOR:
++ DBG(3, "USB_REQ_GET_DESCRIPTOR()\n");
++ break;
+
-+ if (!configured) {
-+ printk(KERN_ERR "kgdboe: configuration incorrect - kgdboe not "
-+ "loaded.\n");
-+ printk(KERN_ERR " Usage: kgdboe=[src-port]@[src-ip]/[dev],"
-+ "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
-+ return -EINVAL;
-+ }
++ case USB_REQ_GET_STATUS: {
++ DBG(3, "USB_REQ_GET_STATUS()\n");
++ service_tx_status_request(pControlRequest);
++ }
++ break;
+
-+ /* Bring it up. */
-+ if (netpoll_setup(&np)) {
-+ printk(KERN_ERR "kgdboe: netpoll_setup failed kgdboe failed\n");
-+ return -EINVAL;
-+ }
++ /* case USB_REQ_SYNC_FRAME:
++ break; */
+
-+ if (kgdb_register_io_module(&local_kgdb_io_ops)) {
-+ netpoll_cleanup(&np);
-+ return -EINVAL;
-+ }
++ default:
++ break;
++ }
+
-+ configured = 2;
++ if ( !handled ) {
++ handled=forward_to_driver(pControlRequest);
++ }
+
-+ return 0;
++ /* now tx! */
++ return handled;
+}
+
-+static int init_kgdboe(void)
++/**
++ * Service a zero data request.
++ * Called for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
++ * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE.
++ *
++ * @param pThis the controller instance
++ * @param pControlRequest the control request to service.
++ * @warning USB_REQ_SET_ADDRESS should be executed QUICKLY
++ * @see is_zerodata_request
++ */
++static int service_zero_data_request(MGC_LinuxCd* pThis,
++ struct usb_ctrlrequest *pControlRequest)
+{
-+ int ret;
++ int handled=1; /* handled, DO NOT not pass down */
++ const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK;
+
-+ /* Already done? */
-+ if (configured == 2)
-+ return 0;
++ DBG(-1002, "<==\n");
+
-+ /* OK, go ahead and do it. */
-+ ret = configure_kgdboe();
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
+
-+ if (configured == 2)
-+ printk(KERN_INFO "kgdboe: debugging over ethernet enabled\n");
++ /* non standard requests are piped to the gadget */
++ if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) {
++ return forward_to_driver(pControlRequest);
++ }
+
-+ return ret;
-+}
++ /* zero data phase */
++ switch (pControlRequest->bRequest) {
+
-+static void cleanup_kgdboe(void)
-+{
-+ netpoll_cleanup(&np);
-+ configured = 0;
-+ kgdb_unregister_io_module(&local_kgdb_io_ops);
-+}
++ case USB_REQ_SET_INTERFACE:
++ DBG(3, "USB_REQ_SET_INTERFACE()\n");
++ handled=0; /* pass it to the gadget */
++ break;
+
-+static int param_set_kgdboe_var(const char *kmessage, struct kernel_param *kp)
-+{
-+ char kmessage_save[MAX_KGDBOE_CONFIG_STR];
-+ int msg_len = strlen(kmessage);
++ case USB_REQ_SET_CONFIGURATION:
++ /* remember state & handle on the end status stage interrupt */
++ DBG(3, "USB_REQ_SET_CONFIGURATION()\n");
++ pThis->bDeviceState = (pControlRequest->wValue & 0xff)
++ ? MGC_STATE_CONFIGURED : MGC_STATE_ADDRESS;
++ handled=0; /* pass it to the gadget */
++ break;
+
-+ if (msg_len + 1 > MAX_KGDBOE_CONFIG_STR) {
-+ printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
-+ kp->name, MAX_KGDBOE_CONFIG_STR - 1);
-+ return -ENOSPC;
-+ }
++ case USB_REQ_SET_ADDRESS:
++ /* remember state & handle on the end status stage interrupt */
++ DBG(3, "USB_REQ_SET_ADDRESS(0x%x)\n",(uint8_t)
++ (pControlRequest->wValue & 0x7f));
+
-+ if (kgdb_connected) {
-+ printk(KERN_ERR "kgdboe: Cannot reconfigure while KGDB is "
-+ "connected.\n");
-+ return 0;
-+ }
++ pThis->bSetAddress = TRUE;
++ pThis->bAddress = (uint8_t)(pControlRequest->wValue & 0x7f);
++ pThis->bDeviceState = MGC_STATE_ADDRESS;
++ break;
+
-+ /* Start the reconfiguration process by saving the old string */
-+ strncpy(kmessage_save, config, sizeof(kmessage_save));
++ case USB_REQ_CLEAR_FEATURE:
++ DBG(3, "USB_REQ_CLEAR_FEATURE()\n");
+
++ switch (bRecip) {
+
-+ /* Copy in the new param and strip out invalid characters so we
-+ * can optionally specify the MAC.
-+ */
-+ strncpy(config, kmessage, sizeof(config));
-+ msg_len--;
-+ while (msg_len > 0 &&
-+ (config[msg_len] < ',' || config[msg_len] > 'f')) {
-+ config[msg_len] = '\0';
-+ msg_len--;
-+ }
++ case USB_RECIP_DEVICE:
++ DBG(3, "USB_RECIP_DEVICE()\n");
++ break;
+
-+ /* Check to see if we are unconfiguring the io module and that it
-+ * was in a fully configured state, as this is the only time that
-+ * netpoll_cleanup should get called
-+ */
-+ if (configured == 2 && strcmp(config, NOT_CONFIGURED_STRING) == 0) {
-+ printk(KERN_INFO "kgdboe: reverting to unconfigured state\n");
-+ cleanup_kgdboe();
-+ return 0;
-+ } else
-+ /* Go and configure with the new params. */
-+ configure_kgdboe();
++ case USB_RECIP_INTERFACE:
++ DBG(3, "USB_RECIP_INTERFACE()\n");
++ break;
+
-+ if (configured == 2)
-+ return 0;
++ case USB_RECIP_ENDPOINT: {
++ const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ;
++ MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ];
+
-+ /* If the new string was invalid, revert to the previous state, which
-+ * is at a minimum not_configured. */
-+ strncpy(config, kmessage_save, sizeof(config));
-+ if (strcmp(kmessage_save, NOT_CONFIGURED_STRING) != 0) {
-+ printk(KERN_INFO "kgdboe: reverting to prior configuration\n");
-+ /* revert back to the original config */
-+ strncpy(config, kmessage_save, sizeof(config));
-+ configure_kgdboe();
-+ }
-+ return 0;
-+}
++ DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );
++ MGC_GadgetSetHalt( &pEnd->end_point, 0);
++ /* select ep0 again */
++ MGC_SelectEnd(pBase, 0);
++ }
++ break;
+
-+static struct kgdb_io local_kgdb_io_ops = {
-+ .read_char = eth_get_char,
-+ .write_char = eth_put_char,
-+ .init = init_kgdboe,
-+ .flush = eth_flush_buf,
-+ .pre_exception = eth_pre_exception_handler,
-+ .post_exception = eth_post_exception_handler
-+};
++ default:
++ break;
++ }
++ break; /* END: CLEAR_FEATURE */
+
-+module_init(init_kgdboe);
-+module_exit(cleanup_kgdboe);
-+module_param_call(kgdboe, param_set_kgdboe_var, param_get_string, &kps, 0644);
-+MODULE_PARM_DESC(kgdboe, " kgdboe=[src-port]@[src-ip]/[dev],"
-+ "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
-diff -Nauprw linux-2.6.20/drivers/net/Makefile ../new/linux-2.6.20/drivers/net/Makefile
---- linux-2.6.20/drivers/net/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -213,6 +213,7 @@ obj-$(CONFIG_ETRAX_ETHERNET) += cris/
- obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
-
- obj-$(CONFIG_NETCONSOLE) += netconsole.o
-+obj-$(CONFIG_KGDBOE) += kgdboe.o
-
- obj-$(CONFIG_FS_ENET) += fs_enet/
-
-diff -Nauprw linux-2.6.20/drivers/net/smc91x.c ../new/linux-2.6.20/drivers/net/smc91x.c
---- linux-2.6.20/drivers/net/smc91x.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/smc91x.c 2007-11-21 11:51:41.000000000 +0530
-@@ -1,3 +1,4 @@
++ case USB_REQ_SET_FEATURE:
++ DBG(3, "USB_REQ_SET_FEATURE()\n");
+
- /*
- * smc91x.c
- * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
-@@ -65,7 +66,6 @@ static const char version[] =
- #define SMC_DEBUG 0
- #endif
-
--
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-@@ -90,6 +90,8 @@ static const char version[] =
-
- #include "smc91x.h"
-
-+#include <linux/delay.h>
++ switch (bRecip) {
+
- #ifdef CONFIG_ISA
- /*
- * the LAN91C111 can be at any of the following port addresses. To change,
-@@ -268,7 +270,6 @@ static void PRINT_PKT(u_char *buf, int l
- #define PRINT_PKT(x...) do { } while(0)
- #endif
-
--
- /* this enables an interrupt in the interrupt mask register */
- #define SMC_ENABLE_INT(x) do { \
- unsigned char mask; \
-@@ -308,7 +309,6 @@ static void PRINT_PKT(u_char *buf, int l
- } \
- } while (0)
-
--
- /*
- * this does a soft reset on the device
- */
-@@ -494,8 +494,7 @@ static inline void smc_rcv(struct net_d
- SMC_GET_PKT_HDR(status, packet_len);
- packet_len &= 0x07ff; /* mask off top bits */
- DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
-- dev->name, packet_number, status,
-- packet_len, packet_len);
-+ dev->name, packet_number, status, packet_len, packet_len);
-
- back:
- if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
-@@ -835,7 +834,6 @@ static void smc_tx(struct net_device *de
- SMC_SELECT_BANK(2);
- }
-
--
- /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
-
- static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
-@@ -927,7 +925,9 @@ static void smc_phy_write(struct net_dev
- smc_mii_out(dev, 0xffffffff, 32);
-
- /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */
-- smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
-+ smc_mii_out(dev,
-+ 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata,
-+ 32);
-
- /* Return to idle state */
- SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
-@@ -961,8 +961,7 @@ static void smc_phy_detect(struct net_de
- id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1);
- id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2);
-
-- DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n",
-- dev->name, id1, id2);
-+ DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", dev->name, id1, id2);
-
- /* Make sure it is a valid identifier */
- if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
-@@ -1184,7 +1183,9 @@ static void smc_phy_configure(struct wor
-
- /* Disable capabilities not selected by our user */
- if (lp->ctl_rspeed != 100)
-- my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
-+ my_ad_caps &=
-+ ~(ADVERTISE_100BASE4 | ADVERTISE_100FULL |
-+ ADVERTISE_100HALF);
-
- if (!lp->ctl_rfduplx)
- my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
-@@ -1314,11 +1315,12 @@ static irqreturn_t smc_interrupt(int irq
- status = SMC_GET_INT();
-
- DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
-- dev->name, status, mask,
-- ({ int meminfo; SMC_SELECT_BANK(0);
-+ dev->name, status, mask, ( {
-+ int meminfo;
-+ SMC_SELECT_BANK(0);
- meminfo = SMC_GET_MIR();
-- SMC_SELECT_BANK(2); meminfo; }),
-- SMC_GET_FIFO());
-+ SMC_SELECT_BANK(2);
-+ meminfo;}), SMC_GET_FIFO());
-
- status &= mask;
- if (!status)
-@@ -1354,10 +1356,18 @@ static irqreturn_t smc_interrupt(int irq
- /* multiple collisions */
- lp->stats.collisions += card_stats & 0xF;
- } else if (status & IM_RX_OVRN_INT) {
-- DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
-- ({ int eph_st; SMC_SELECT_BANK(0);
-- eph_st = SMC_GET_EPH_STATUS();
-- SMC_SELECT_BANK(2); eph_st; }) );
-+ DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, ( {
-+ int
-+ eph_st;
-+ SMC_SELECT_BANK
-+ (0);
-+ eph_st
-+ =
-+ SMC_GET_EPH_STATUS
-+ ();
-+ SMC_SELECT_BANK
-+ (2);
-+ eph_st;}));
- SMC_ACK_INT(IM_RX_OVRN_INT);
- lp->stats.rx_errors++;
- lp->stats.rx_fifo_errors++;
-@@ -1500,7 +1510,8 @@ static void smc_set_multicast_list(struc
- struct dev_mc_list *cur_addr;
-
- /* table for flipping the order of 3 bits */
-- static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7};
-+ static const unsigned char invert3[] =
-+ { 0, 4, 2, 6, 1, 5, 3, 7 };
-
- /* start with a table of all zeros: reject all */
- memset(multicast_table, 0, sizeof(multicast_table));
-@@ -1553,14 +1564,12 @@ static void smc_set_multicast_list(struc
- spin_unlock_irq(&lp->lock);
- }
-
--
- /*
- * Open and Initialize the board
- *
- * Set up everything, reset the card, etc..
- */
--static int
--smc_open(struct net_device *dev)
-+static int smc_open(struct net_device *dev)
- {
- struct smc_local *lp = netdev_priv(dev);
-
-@@ -1659,8 +1668,7 @@ smc_ethtool_getsettings(struct net_devic
- spin_unlock_irq(&lp->lock);
- } else {
- cmd->supported = SUPPORTED_10baseT_Half |
-- SUPPORTED_10baseT_Full |
-- SUPPORTED_TP | SUPPORTED_AUI;
-+ SUPPORTED_10baseT_Full | SUPPORTED_TP | SUPPORTED_AUI;
-
- if (lp->ctl_rspeed == 10)
- cmd->speed = SPEED_10;
-@@ -1670,7 +1678,8 @@ smc_ethtool_getsettings(struct net_devic
- cmd->autoneg = AUTONEG_DISABLE;
- cmd->transceiver = XCVR_INTERNAL;
- cmd->port = 0;
-- cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
-+ cmd->duplex =
-+ lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
-
- ret = 0;
- }
-@@ -1691,8 +1700,8 @@ smc_ethtool_setsettings(struct net_devic
- } else {
- if (cmd->autoneg != AUTONEG_DISABLE ||
- cmd->speed != SPEED_10 ||
-- (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
-- (cmd->port != PORT_TP && cmd->port != PORT_AUI))
-+ (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
-+ || (cmd->port != PORT_TP && cmd->port != PORT_AUI))
- return -EINVAL;
-
- // lp->port = cmd->port;
-@@ -1712,7 +1721,8 @@ smc_ethtool_getdrvinfo(struct net_device
- {
- strncpy(info->driver, CARDNAME, sizeof(info->driver));
- strncpy(info->version, version, sizeof(info->version));
-- strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
-+ strncpy(info->bus_info, dev->class_dev.dev->bus_id,
-+ sizeof(info->bus_info));
- }
-
- static int smc_ethtool_nwayreset(struct net_device *dev)
-@@ -1839,7 +1849,7 @@ static int __init smc_findirq(void __iom
- * o actually GRAB the irq.
- * o GRAB the region
- */
--static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
-+int __init smc_probe(struct net_device *dev, void __iomem * ioaddr)
- {
- struct smc_local *lp = netdev_priv(dev);
- static int version_printed = 0;
-@@ -1880,6 +1890,8 @@ static int __init smc_probe(struct net_d
- * register
- */
- SMC_SELECT_BANK(1);
-+ mdelay(100);
-+ val = SMC_CURRENT_BANK();
- val = SMC_GET_BASE();
- val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
- if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
-@@ -1918,6 +1930,7 @@ static int __init smc_probe(struct net_d
-
- /* Get the MAC address */
- SMC_SELECT_BANK(1);
++ case USB_RECIP_DEVICE:
++ DBG(3, "USB_RECIP_DEVICE()\n");
+
- SMC_GET_MAC_ADDR(dev->dev_addr);
-
- /* now, reset the chip, and put it into a known state */
-@@ -2005,7 +2018,11 @@ static int __init smc_probe(struct net_d
- }
-
- /* Grab the IRQ */
-- retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
-+ printk("dev->irq = %d\n", dev->irq);
++ switch (pControlRequest->wValue) {
+
-+ retval =
-+ request_irq(dev->irq, smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
++ case 1:
++ DBG(3, "REMOTE_WAKEUP()\n");
++ while (0) { } /* remote wakeup */
++ break;
+
- if (retval)
- goto err_out;
-
-@@ -2045,7 +2062,8 @@ static int __init smc_probe(struct net_d
- if (lp->phy_type == 0) {
- PRINTK("%s: No PHY found\n", dev->name);
- } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) {
-- PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name);
-+ PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n",
-+ dev->name);
- } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
- PRINTK("%s: PHY LAN83C180\n", dev->name);
- }
-@@ -2066,7 +2084,8 @@ static int smc_enable_device(struct plat
- void __iomem *addr;
- struct resource * res;
-
-- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-+ res =
-+ platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
- if (!res)
- return 0;
-
-@@ -2122,7 +2141,8 @@ static int smc_enable_device(struct plat
-
- static int smc_request_attrib(struct platform_device *pdev)
- {
-- struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-+ struct resource *res =
-+ platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-
- if (!res)
- return 0;
-@@ -2135,7 +2155,8 @@ static int smc_request_attrib(struct pla
-
- static void smc_release_attrib(struct platform_device *pdev)
- {
-- struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-+ struct resource *res =
-+ platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-
- if (res)
- release_mem_region(res->start, ATTRIB_SIZE);
-@@ -2159,8 +2180,12 @@ static inline void smc_request_datacs(st
- }
- }
-
--static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
-+static void smc_release_datacs(struct platform_device *pdev,
-+ struct net_device *ndev)
- {
-+// struct smc_local *lp = netdev_priv(ndev);
-+// struct resource *res =
-+// platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
- if (SMC_CAN_USE_DATACS) {
- struct smc_local *lp = netdev_priv(ndev);
- struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
-@@ -2201,7 +2226,6 @@ static int smc_drv_probe(struct platform
- goto out;
- }
-
--
- if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
- ret = -EBUSY;
- goto out;
-@@ -2240,6 +2264,7 @@ static int smc_drv_probe(struct platform
- }
-
- platform_set_drvdata(pdev, ndev);
++ case 2:
++ if (pControlRequest->wIndex & 0xff) {
++ handled=-EINVAL;
++ } else {
++ uint16_t wTest;
+
- ret = smc_probe(ndev, addr);
- if (ret != 0)
- goto out_iounmap;
-@@ -2278,7 +2303,6 @@ static int smc_drv_remove(struct platfor
- platform_set_drvdata(pdev, NULL);
-
- unregister_netdev(ndev);
--
- free_irq(ndev->irq, ndev);
-
- #ifdef SMC_USE_PXA_DMA
-@@ -2348,8 +2372,6 @@ static int __init smc_init(void)
- #ifdef CONFIG_ISA
- if (io == -1)
- printk(KERN_WARNING
-- "%s: You shouldn't use auto-probing with insmod!\n",
-- CARDNAME);
- #endif
- #endif
-
-diff -Nauprw linux-2.6.20/drivers/net/smc91x.h ../new/linux-2.6.20/drivers/net/smc91x.h
---- linux-2.6.20/drivers/net/smc91x.h 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/smc91x.h 2007-11-21 11:51:41.000000000 +0530
-@@ -34,7 +34,6 @@
- #ifndef _SMC91X_H_
- #define _SMC91X_H_
-
--
- /*
- * Define your architecture specific bus configuration parameters here.
- */
-@@ -163,8 +162,7 @@
- #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
-
- /* We actually can't write halfwords properly if not word aligned */
--static inline void
--SMC_outw(u16 val, void __iomem *ioaddr, int reg)
-+static inline void SMC_outw(u16 val, void __iomem * ioaddr, int reg)
- {
- if (reg & 2) {
- unsigned int v = val << 16;
-@@ -199,6 +197,77 @@ SMC_outw(u16 val, void __iomem *ioaddr,
- || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
- ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
-
-+#elif defined(CONFIG_ARCH_NOMADIK)
++ DBG(3, "ENTERING TESTMODE\n");
++ pThis->bTestMode = TRUE;
++ wTest = (uint8_t)pControlRequest->wIndex >> 8;
++ switch(wTest) {
+
-+#include <asm/hardware.h>
++ case 1:
++ DBG(3, "TEST_J\n");
++ /* TEST_J */
++ pThis->bTestModeValue = MGC_M_TEST_J;
++ break;
+
-+#define SMC_CAN_USE_8BIT 0
-+#define SMC_CAN_USE_16BIT 1
-+#define SMC_CAN_USE_32BIT 0
-+#define SMC_IO_SHIFT 0
-+#define SMC_NOWAIT 0
++ case 2:
++ /* TEST_K */
++ DBG(3, "TEST_K\n");
++ pThis->bTestModeValue = MGC_M_TEST_K;
++ break;
+
-+#define SMC_inb(a, r) readb((a) + (r))
-+#define SMC_outb(v, a, r) writeb(v, (a) + (r))
-+#define SMC_inw(a, r) readw((a) + (r))
-+#define SMC_outw(v, a, r) writew(v, (a) + (r))
-+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
-+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
-+#define SMC_inl(a, r) readl((a) + (r))
-+#define SMC_outl(v, a, r) writel(v, (a) + (r))
-+#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
-+#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
++ case 3:
++ /* TEST_SE0_NAK */
++ DBG(3, "TEST_SE0_NAK\n");
++ pThis->bTestModeValue = MGC_M_TEST_SE0_NAK;
++ break;
+
-+#ifdef CONFIG_NOMADIK_NHK15
-+#define SMC_IRQ_FLAGS SA_TRIGGER_RISING
-+#else
-+#define SMC_IRQ_FLAGS (SA_SHIRQ)
++ case 4:
++ /* TEST_PACKET */
++ DBG(3, "TEST_PACKET\n");
++ pThis->bTestModeValue = MGC_M_TEST_PACKET;
++ break;
++
++ default:
++ /* my gadget might know what to do with it */
++ break;
++ }
++ }
++ break;
++#ifdef MUSB_OTG
++ case 3:
++ GADGET_SET_B_HNP_ENABLE(pThis->pGadget, 1);
++ MGC_OtgMachineSetFeature(&(pThis->OtgMachine),
++ pControlRequest->wValue);
++ break;
++
++ case 4:
++ GADGET_SET_A_HNP_SUPPORT(pThis->pGadget, 1);
++ MGC_OtgMachineSetFeature(&(pThis->OtgMachine),
++ pControlRequest->wValue);
++ break;
++
++ case 5:
++ GADGET_SET_A_ALT_HNP_SUPPORT(pThis->pGadget, 1);
++ MGC_OtgMachineSetFeature(&(pThis->OtgMachine),
++ pControlRequest->wValue);
++ break;
+#endif
++ }
++ break;
+
-+static unsigned char new_mac_addr[MAX_ADDR_LEN] =
-+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
++ case USB_RECIP_INTERFACE:
++ DBG(3, "USB_RECIP_INTERFACE()\n");
++ break;
+
-+static int smc_mac_setup(char *opt)
-+{
-+ char *cur = opt, *delim;
-+ if (*cur != 0) {
-+ /* Get the new MAC address */
-+ if ((delim = strchr(cur, ':')) == NULL)
-+ goto parse_failed;
-+ *delim = 0;
-+ new_mac_addr[0] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+ new_mac_addr[0] &= 0xFE; /* clear multicast bit */
-+ new_mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
-+ cur = delim + 1;
-+ if ((delim = strchr(cur, ':')) == NULL)
-+ goto parse_failed;
-+ *delim = 0;
-+ new_mac_addr[1] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+ cur = delim + 1;
-+ if ((delim = strchr(cur, ':')) == NULL)
-+ goto parse_failed;
-+ *delim = 0;
-+ new_mac_addr[2] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+ cur = delim + 1;
-+ if ((delim = strchr(cur, ':')) == NULL)
-+ goto parse_failed;
-+ *delim = 0;
-+ new_mac_addr[3] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+ cur = delim + 1;
-+ if ((delim = strchr(cur, ':')) == NULL)
-+ goto parse_failed;
-+ *delim = 0;
-+ new_mac_addr[4] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+ cur = delim + 1;
-+ new_mac_addr[5] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+ }
-+ return 0;
-+parse_failed:
-+ printk(KERN_INFO "mac=: couldn't parse config at %s!\n", cur);
-+ return -1;
++ case USB_RECIP_ENDPOINT: {
++ const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ;
++ MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ];
++
++ DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );
++ MGC_GadgetSetHalt(&pEnd->end_point, 1);
++
++ /* select ep0 again */
++ MGC_SelectEnd(pBase, 0);
++ }
++ break;
++
++ }
++ break; /* END: SET_FEATURE */
++
++ default:
++ handled=0;
++ break;
++ }
++
++ /* standard request not handed by this code go to the gadget */
++ if ( !handled ) {
++ handled=forward_to_driver(pControlRequest);
++ }
++
++ DBG(-1002, "==>\n");
++ return handled;
+}
+
-+__setup("mac=", smc_mac_setup);
-
- #elif defined(CONFIG_SH_SH4202_MICRODEV)
-
-@@ -477,7 +546,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- }
- #endif /* SMC_USE_PXA_DMA */
-
--
- /*
- * Everything a particular hardware setup needs should have been defined
- * at this point. Add stubs for the undefined cases, mainly to avoid
-@@ -485,12 +553,14 @@ smc_pxa_dma_irq(int dma, void *dummy)
- * use of them.
- */
-
-+#if 0 /*Vaibhav*/
- #if ! SMC_CAN_USE_32BIT
- #define SMC_inl(ioaddr, reg) ({ BUG(); 0; })
- #define SMC_outl(x, ioaddr, reg) BUG()
- #define SMC_insl(a, r, p, l) BUG()
- #define SMC_outsl(a, r, p, l) BUG()
- #endif
-+#endif
-
- #if !defined(SMC_insl) || !defined(SMC_outsl)
- #define SMC_insl(a, r, p, l) BUG()
-@@ -522,14 +592,18 @@ smc_pxa_dma_irq(int dma, void *dummy)
-
- #endif
-
-+#if 0 /*Vaibhav*/
- #if !defined(SMC_insw) || !defined(SMC_outsw)
- #define SMC_insw(a, r, p, l) BUG()
- #define SMC_outsw(a, r, p, l) BUG()
- #endif
-+#endif
-
- #if ! SMC_CAN_USE_8BIT
-+#if 0 /*Vaibhav*/
- #define SMC_inb(ioaddr, reg) ({ BUG(); 0; })
- #define SMC_outb(x, ioaddr, reg) BUG()
-+#endif
- #define SMC_insb(a, r, p, l) BUG()
- #define SMC_outsb(a, r, p, l) BUG()
- #endif
-@@ -569,7 +643,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- */
- #define BANK_SELECT (14 << SMC_IO_SHIFT)
-
--
- // Transmit Control Register
- /* BANK 0 */
- #define TCR_REG SMC_REG(0x0000, 0)
-@@ -588,7 +661,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- /* the default settings for the TCR register : */
- #define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN)
-
--
- // EPH Status Register
- /* BANK 0 */
- #define EPH_STATUS_REG SMC_REG(0x0002, 0)
-@@ -607,7 +679,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin
- #define ES_TXUNRN 0x8000 // Tx Underrun
-
--
- // Receive Control Register
- /* BANK 0 */
- #define RCR_REG SMC_REG(0x0004, 0)
-@@ -624,17 +695,14 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN)
- #define RCR_CLEAR 0x0 // set it to a base state
-
--
- // Counter Register
- /* BANK 0 */
- #define COUNTER_REG SMC_REG(0x0006, 0)
-
--
- // Memory Information Register
- /* BANK 0 */
- #define MIR_REG SMC_REG(0x0008, 0)
-
--
- // Receive/Phy Control Register
- /* BANK 0 */
- #define RPC_REG SMC_REG(0x000A, 0)
-@@ -661,14 +729,12 @@ smc_pxa_dma_irq(int dma, void *dummy)
-
- #define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
-
--
- /* Bank 0 0x0C is reserved */
-
- // Bank Select Register
- /* All Banks */
- #define BSR_REG 0x000E
-
--
- // Configuration Reg
- /* BANK 1 */
- #define CONFIG_REG SMC_REG(0x0000, 1)
-@@ -680,24 +746,20 @@ smc_pxa_dma_irq(int dma, void *dummy)
- // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
- #define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
-
--
- // Base Address Register
- /* BANK 1 */
- #define BASE_REG SMC_REG(0x0002, 1)
-
--
- // Individual Address Registers
- /* BANK 1 */
- #define ADDR0_REG SMC_REG(0x0004, 1)
- #define ADDR1_REG SMC_REG(0x0006, 1)
- #define ADDR2_REG SMC_REG(0x0008, 1)
-
--
- // General Purpose Register
- /* BANK 1 */
- #define GP_REG SMC_REG(0x000A, 1)
-
--
- // Control Register
- /* BANK 1 */
- #define CTL_REG SMC_REG(0x000C, 1)
-@@ -710,7 +772,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define CTL_RELOAD 0x0002 // When set reads EEPROM into registers
- #define CTL_STORE 0x0001 // When set stores registers into EEPROM
-
--
- // MMU Command Register
- /* BANK 2 */
- #define MMU_CMD_REG SMC_REG(0x0000, 2)
-@@ -724,18 +785,15 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit
- #define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs
-
--
- // Packet Number Register
- /* BANK 2 */
- #define PN_REG SMC_REG(0x0002, 2)
-
--
- // Allocation Result Register
- /* BANK 2 */
- #define AR_REG SMC_REG(0x0003, 2)
- #define AR_FAILED 0x80 // Alocation Failed
-
--
- // TX FIFO Ports Register
- /* BANK 2 */
- #define TXFIFO_REG SMC_REG(0x0004, 2)
-@@ -755,17 +813,14 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access
- #define PTR_READ 0x2000 // When 1 the operation is a read
-
--
- // Data Register
- /* BANK 2 */
- #define DATA_REG SMC_REG(0x0008, 2)
-
--
- // Interrupt Status/Acknowledge Register
- /* BANK 2 */
- #define INT_REG SMC_REG(0x000C, 2)
-
--
- // Interrupt Mask Register
- /* BANK 2 */
- #define IM_REG SMC_REG(0x000D, 2)
-@@ -778,7 +833,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define IM_TX_INT 0x02 // Transmit Interrupt
- #define IM_RCV_INT 0x01 // Receive Interrupt
-
--
- // Multicast Table Registers
- /* BANK 3 */
- #define MCAST_REG1 SMC_REG(0x0000, 3)
-@@ -786,7 +840,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define MCAST_REG3 SMC_REG(0x0004, 3)
- #define MCAST_REG4 SMC_REG(0x0006, 3)
-
--
- // Management Interface Register (MII)
- /* BANK 3 */
- #define MII_REG SMC_REG(0x0008, 3)
-@@ -796,13 +849,11 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define MII_MDI 0x0002 // MII Input, pin MDI
- #define MII_MDO 0x0001 // MII Output, pin MDO
-
--
- // Revision Register
- /* BANK 3 */
- /* ( hi: chip id low: rev # ) */
- #define REV_REG SMC_REG(0x000A, 3)
-
--
- // Early RCV Register
- /* BANK 3 */
- /* this is NOT on SMC9192 */
-@@ -810,12 +861,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received
- #define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask
-
--
- // External Register
- /* BANK 7 */
- #define EXT_REG SMC_REG(0x0000, 7)
-
--
- #define CHIP_9192 3
- #define CHIP_9194 4
- #define CHIP_9195 5
-@@ -834,8 +883,8 @@ static const char * chip_ids[ 16 ] = {
- /* 8 */ "SMC91C100FD",
- /* 9 */ "SMC91C11xFD",
- NULL, NULL, NULL,
-- NULL, NULL, NULL};
--
-+ NULL, NULL, NULL
-+};
-
- /*
- . Receive status bits
-@@ -849,7 +898,6 @@ static const char * chip_ids[ 16 ] = {
- #define RS_MULTICAST 0x0001
- #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
-
--
- /*
- * PHY IDs
- * LAN83C183 == LAN91C111 Internal PHY
-@@ -879,7 +927,6 @@ static const char * chip_ids[ 16 ] = {
- #define PHY_CFG1_TLVL_MASK 0x003C
- #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time
-
--
- // PHY Configuration Register 2
- #define PHY_CFG2_REG 0x11
- #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled
-@@ -904,7 +951,6 @@ static const char * chip_ids[ 16 ] = {
- #define PHY_MASK_REG 0x13 // Interrupt Mask
- // Uses the same bit definitions as PHY_INT_REG
-
--
- /*
- * SMC91C96 ethernet config and status registers.
- * These are in the "attribute" space.
-@@ -922,7 +968,6 @@ static const char * chip_ids[ 16 ] = {
-
- #define ATTRIB_SIZE ((64*1024) << SMC_IO_SHIFT)
-
--
- /*
- * Macros to abstract register access according to the data bus
- * capabilities. Please use those and not the in/out primitives.
-@@ -1089,7 +1134,13 @@ static const char * chip_ids[ 16 ] = {
- #define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG)
-
- #ifndef SMC_GET_MAC_ADDR
-+#ifdef CONFIG_ARCH_NOMADIK
- #define SMC_GET_MAC_ADDR(addr) \
-+ if (new_mac_addr[0] == 0xFF) { \
-+ printk("%s: Setting Random MAC addr\n", CARDNAME); \
-+ random_ether_addr(new_mac_addr); \
-+ } \
-+ SMC_SET_MAC_ADDR(new_mac_addr); \
- do { \
- unsigned int __v; \
- __v = SMC_inw( ioaddr, ADDR0_REG ); \
-@@ -1099,6 +1150,18 @@ static const char * chip_ids[ 16 ] = {
- __v = SMC_inw( ioaddr, ADDR2_REG ); \
- addr[4] = __v; addr[5] = __v >> 8; \
- } while (0)
-+#else
-+#define SMC_GET_MAC_ADDR(addr) \
-+ do { \
-+ unsigned int __v; \
-+ __v = SMC_inw( ioaddr, ADDR0_REG ); \
-+ addr[0] = __v; addr[1] = __v >> 8; \
-+ __v = SMC_inw( ioaddr, ADDR1_REG ); \
-+ addr[2] = __v; addr[3] = __v >> 8; \
-+ __v = SMC_inw( ioaddr, ADDR2_REG ); \
-+ addr[4] = __v; addr[5] = __v >> 8; \
-+ } while (0)
-+#endif
- #endif
-
- #define SMC_SET_MAC_ADDR(addr) \
-diff -Nauprw linux-2.6.20/drivers/serial/amba-pl011.c ../new/linux-2.6.20/drivers/serial/amba-pl011.c
---- linux-2.6.20/drivers/serial/amba-pl011.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/serial/amba-pl011.c 2007-11-21 11:51:41.000000000 +0530
-@@ -52,13 +52,32 @@
-
- #include <asm/io.h>
- #include <asm/sizes.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-
--#define UART_NR 14
-+/*
-+ * Definations here is used instead of this which is defined in platform.h
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Complete a request on enpdpoint 0. This is called after a competition
++ * IRQ on ep0 has occourred.
++ * @warning Executed @ interrupt time; complete CANNOT sleep.
+ */
++void mgc_complete_ep0_request(void)
++{
++ struct usb_request *pRequest;
++ MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
+
-+#ifndef UART_NR
-+#define UART_NR 14 /*default generic value */
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_LOCKED(&MGC_aGadgetLocalEnd[0]);
+#endif
+
-+#ifndef UART_FIFO_SIZE
-+#define UART_FIFO_SIZE 16 /*default generic value */
-+#endif
++ spin_lock( &MGC_aGadgetLocalEnd[0].Lock );
++ pRequest=MGC_CurrentRequest( &MGC_aGadgetLocalEnd[0] );
+
-+#ifndef UART_PER_ID
-+#define UART_PER_ID 0x00041011 /*default uart peripharal id */
++ DBG(3, "completing request pRequest=%p\n", pRequest);
++
++ /* this is interrupt code, it cannot sleep! */
++ if ( pRequest ) {
++ list_del( &pRequest->list );
++ INIT_LIST_HEAD( &MGC_aGadgetLocalEnd[0].req_list );
++
++ spin_unlock( &MGC_aGadgetLocalEnd[0].Lock );
++ if ( pRequest->complete ) {
++ pRequest->complete(&MGC_aGadgetLocalEnd[0].end_point,
++ pRequest);
++ }
++ } else {
++ spin_unlock( &MGC_aGadgetLocalEnd[0].Lock );
++ }
++
++ pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
++}
++
++/**
++ * handle the completition interrupt on endpoint 0.
++ */
++static void handle_ep0_completition_irq(void)
++{
++ MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++ const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++ DBG(3, "<==\n");
++ DBG(4, "post event interrupts ep0stage=%s\n",
++ decode_ep0stage(pThis->bEnd0Stage));
++
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
+#endif
+
-+#ifndef UART_PER_MASK
-+#define UART_PER_MASK 0x000fffff /*default uart peripharal mask */
++ switch (pThis->bEnd0Stage) {
++
++ /* end of sequence #2 (RX state) or #3 (no data) */
++ case MGC_END0_STAGE_STATUSIN:
++ DBG(-1001, "MGC_END0_STAGE_STATUSIN request\n");
++
++ /* update address (if needed) only @ the end of the
++ * status phase per standard. The guide is WRONG!
++ */
++ if(pThis->bSetAddress) {
++ pThis->bSetAddress = FALSE;
++ MGC_Write8(pBase, MGC_O_HDRC_FADDR, pThis->bAddress);
++#ifdef MUSB_MONITOR_DATA
++ MGC_EnableDebug();
+#endif
-
- #define SERIAL_AMBA_MAJOR 204
- #define SERIAL_AMBA_MINOR 64
- #define SERIAL_AMBA_NR UART_NR
--
- #define AMBA_ISR_PASS_LIMIT 256
-
- #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
-@@ -102,9 +121,16 @@ static void pl011_stop_rx(struct uart_po
- static void pl011_enable_ms(struct uart_port *port)
- {
- struct uart_amba_port *uap = (struct uart_amba_port *)port;
-+ unsigned cr;
-
-- uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
-+ uap->im |=
-+ UART011_RIMIM | UART011_CTSMIM | UART011_DCDMIM | UART011_DSRMIM;
- writew(uap->im, uap->port.membase + UART011_IMSC);
++ }
+
-+ cr = readw(uap->port.membase + UART011_CR);
-+ barrier();
-+ cr = cr | UART_CONTROL_MASK_CTSFLOW | UART_CONTROL_MASK_RTSFLOW;
-+ writew(cr, uap->port.membase + UART011_CR);
- }
-
- static void pl011_rx_chars(struct uart_amba_port *uap)
-@@ -115,6 +141,7 @@ static void pl011_rx_chars(struct uart_a
- status = readw(uap->port.membase + UART01x_FR);
- while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
- ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
++ /* enter test mode if needed */
++ if(pThis->bTestMode) {
++ DBG(-1001, "entering TESTMODE\n");
+
- flag = TTY_NORMAL;
- uap->port.icount.rx++;
-
-@@ -174,7 +201,9 @@ static void pl011_tx_chars(struct uart_a
- }
-
- count = uap->port.fifosize >> 1;
++ if (MGC_M_TEST_PACKET == pThis->bTestModeValue) {
++ MGC_HdrcLoadFifo(pBase, 0, sizeof(MGC_aTestPacket),
++ MGC_aTestPacket);
++ }
+
- do {
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0); /* select ep0 */
++ MGC_Write8(pBase, MGC_O_HDRC_TESTMODE,
++ pThis->bTestModeValue);
++ spin_unlock(&pThis->Lock);
++ }
+
- writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- uap->port.icount.tx++;
-@@ -318,6 +347,7 @@ static int pl011_startup(struct uart_por
- struct uart_amba_port *uap = (struct uart_amba_port *)port;
- unsigned int cr;
- int retval;
-+ int status, ch;
-
- /*
- * Try to enable the clock producer.
-@@ -331,12 +361,19 @@ static int pl011_startup(struct uart_por
- /*
- * Allocate the IRQ
- */
-- retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
-+ retval =
-+ request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap);
- if (retval)
- goto clk_dis;
-
-- writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
-- uap->port.membase + UART011_IFLS);
-+ /*
-+ *writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
-+ *uap->port.membase + UART011_IFLS);
-+ */
++ DBG(-1001, "completing posted request (if any)\n");
++ mgc_complete_ep0_request();
++ break;
+
-+ writew(UART_TX_RX_HALF, uap->port.membase + UART011_IFLS);
-+ /* Clearing interrupts */
-+ writew(0x7ff, uap->port.membase + UART011_ICR);
-
- /*
- * Provoke TX FIFO interrupt into asserting.
-@@ -346,7 +383,11 @@ static int pl011_startup(struct uart_por
- writew(0, uap->port.membase + UART011_FBRD);
- writew(1, uap->port.membase + UART011_IBRD);
- writew(0, uap->port.membase + UART011_LCRH);
-- writew(0, uap->port.membase + UART01x_DR);
-+ writew('Z', uap->port.membase + UART01x_DR);
++ /* sequence #1: write to host (TX state) */
++ case MGC_END0_STAGE_STATUSOUT:
++ DBG(-1001, "completing posted request (if any)\n");
++ mgc_complete_ep0_request();
++ break;
+
-+ barrier();
-+ ch = readw(uap->port.membase + UART01x_DR);
++ case MGC_END0_STAGE_TX:
++ DBG(-1001, "TX changeing ep status\n");
++ if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) {
++ pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT;
++ }
++ break;
+
- while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
- barrier();
-
-@@ -356,7 +397,14 @@ static int pl011_startup(struct uart_por
- /*
- * initialise the old status of the modem signals
- */
-- uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
-+ uap->old_status =
-+ readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
++ case MGC_END0_STAGE_RX:
++ DBG(-1001, "RX changeing ep status\n");
++ if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) {
++ pThis->bEnd0Stage=MGC_END0_STAGE_STATUSIN;
++ }
++ break;
+
-+ status = readw(uap->port.membase + UART01x_FR);
-+ while ((status & UART01x_FR_RXFE) == 0) {
-+ ch = readw(uap->port.membase + UART01x_DR);
-+ status = readw(uap->port.membase + UART01x_FR);
-+ }
-
- /*
- * Finally, enable interrupts
-@@ -396,7 +444,8 @@ static void pl011_shutdown(struct uart_p
- /*
- * disable the port
- */
-- writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
-+ writew(UART01x_CR_UARTEN | UART011_CR_TXE,
-+ uap->port.membase + UART011_CR);
-
- /*
- * disable break condition and fifos
-@@ -658,6 +707,7 @@ static int __init pl011_console_setup(st
- * if so, search for the first available port that does have
- * console support.
- */
++ default: /* IT WAS STALLED */
++ DBG(-1002, "recovering from stall? ep0stage=%s\n",
++ decode_ep0stage(pThis->bEnd0Stage));
++ pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
++ break;
++ }
+
- if (co->index >= UART_NR)
- co->index = 0;
- uap = amba_ports[co->index];
-@@ -700,6 +750,28 @@ static struct uart_driver amba_reg = {
- .cons = AMBA_CONSOLE,
- };
-
-+#ifdef CONFIG_PM
-+static int pl011_suspend(struct amba_device *dev, pm_message_t state)
-+{
-+ struct uart_amba_port *uap = amba_get_drvdata(dev);
++ DBG(3, "==>\n");
++}
+
-+ if (uap)
-+ uart_suspend_port(&amba_reg, &uap->port);
+
-+ return 0;
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Handle ep0 in receive state. Called to start a receie and on each interrupt
++ * when receiving data on ep0.
++ */
++int ep0_rxstate(void) {
++ MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++ const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]);
++ struct usb_request *pRequest=MGC_CurrentRequest(pEnd);
++
++ /* nothign for now */
++ DBG(-1002, "<==\n");
++
++ if ( pRequest->actual==0 ) {
++ /* ack the request first */
++ DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_CSR0_P_SVDRXPKTRDY);
++ spin_unlock(&pThis->Lock);
++ }
++
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_LOCKED(&pEnd->Lock);
++#endif
++
++ DBG(-1002, "==>\n");
++
++ return 0;
+}
+
-+static int pl011_resume(struct amba_device *dev)
++/**
++ * Handle ep0 in transmit state. Called to start a receie and on each interrupt
++ * when transmitting data on ep0.
++ */
++int ep0_txstate(void)
+{
-+ struct uart_amba_port *uap = amba_get_drvdata(dev);
++ unsigned long flags;
++ MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++ const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]);
++ struct usb_request *pRequest=MGC_CurrentRequest(pEnd);
++ uint16_t wCsrVal = MGC_M_CSR0_TXPKTRDY;
++ uint8_t* pFifoSource;
++ uint8_t wFifoCount;
+
-+ if (uap)
-+ uart_resume_port(&amba_reg, &uap->port);
++ DBG(-1002, "<==\n");
+
-+ return 0;
-+}
++#ifdef MUSB_PARANOID
++ if ( !pThis || !pRequest ) {
++ ERR("pThis=%p, pRequest=%p", pThis, pRequest);
++ return -EINVAL;
++ }
+#endif
+
- static int pl011_probe(struct amba_device *dev, void *id)
- {
- struct uart_amba_port *uap;
-@@ -739,9 +811,10 @@ static int pl011_probe(struct amba_devic
- uap->port.membase = base;
- uap->port.iotype = UPIO_MEM;
- uap->port.irq = dev->irq[0];
-- uap->port.fifosize = 16;
-+ uap->port.fifosize = UART_FIFO_SIZE;
- uap->port.ops = &amba_pl011_pops;
- uap->port.flags = UPF_BOOT_AUTOCONF;
-+
- uap->port.line = i;
-
- amba_ports[i] = uap;
-@@ -782,8 +855,8 @@ static int pl011_remove(struct amba_devi
-
- static struct amba_id pl011_ids[] __initdata = {
- {
-- .id = 0x00041011,
-- .mask = 0x000fffff,
-+ .id = UART_PER_ID,
-+ .mask = UART_PER_MASK,
- },
- { 0, 0 },
- };
-@@ -795,6 +868,10 @@ static struct amba_driver pl011_driver =
- .id_table = pl011_ids,
- .probe = pl011_probe,
- .remove = pl011_remove,
-+#ifdef CONFIG_PM
-+ .suspend = pl011_suspend,
-+ .resume = pl011_resume,
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++ ASSERT_SPINLOCK_LOCKED(&pEnd->Lock);
+#endif
- };
-
- static int __init pl011_init(void)
-diff -Nauprw linux-2.6.20/drivers/spi/Kconfig ../new/linux-2.6.20/drivers/spi/Kconfig
---- linux-2.6.20/drivers/spi/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/spi/Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -65,6 +65,14 @@ config SPI_BITBANG
- need it. You only need to select this explicitly to support driver
- modules that aren't part of this kernel tree.
-
-+config NOMADIK_SPI
-+ tristate "Nomadik SPI master"
-+ depends on SPI_MASTER && EXPERIMENTAL
-+ default y
-+ help
-+ This enables using the Nomadik SPI controller in master
-+ mode.
+
- config SPI_BUTTERFLY
- tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
- depends on SPI_MASTER && PARPORT && EXPERIMENTAL
-diff -Nauprw linux-2.6.20/drivers/spi/Makefile ../new/linux-2.6.20/drivers/spi/Makefile
---- linux-2.6.20/drivers/spi/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/spi/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -12,6 +12,8 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
-
- # SPI master controller drivers (bus)
- obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
-+obj-$(CONFIG_NOMADIK_SPI) += nmdkmod_spi.o
-+nmdkmod_spi-objs := spi-nomadik.o
- obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
- obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
- obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
-diff -Nauprw linux-2.6.20/drivers/spi/spi-nomadik.c ../new/linux-2.6.20/drivers/spi/spi-nomadik.c
---- linux-2.6.20/drivers/spi/spi-nomadik.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/spi/spi-nomadik.c 2008-07-04 23:45:22.000000000 +0530
-@@ -0,0 +1,1000 @@
++ spin_lock_irqsave(&pThis->Lock, flags);
++ MGC_SelectEnd(pBase, 0);
++
++ if ( pRequest->actual==0 ) {
++ /* ack the request first */
++ DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_CSR0_P_SVDRXPKTRDY);
++ }
++
++ /* load the data */
++ pFifoSource = (uint8_t*)pRequest->buf+pRequest->actual;
++ wFifoCount =min((int)MGC_END0_FIFOSIZE, (int)(pRequest->length-pRequest->actual));
++ MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoSource);
++ pRequest->actual+=wFifoCount; /* done */
++
++ /* update the flags */
++ if ( wFifoCount < MUSB_MAX_END0_PACKET ) {
++ wCsrVal |= MGC_M_CSR0_P_DATAEND;
++ pRequest->status=0; /* done */
++ }
++
++ /* send it out! (this will trigger the ep0 completition IRQ)
++ * serviced in interrupt_complete()
++ */
++ DBG(4, "wrote wFifoCount=%d bytes, wCsrVal=%s\n", wFifoCount,
++ decode_csr0(wCsrVal) );
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
++ spin_unlock_irqrestore(&pThis->Lock, flags);
++
++ DBG(-1002, "==>\n");
++ return 0;
++}
++
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Handle ep0 interrupt of a device, lock & release pThis. This is the main
++ * entry point of the gadget Ep0 handling code.
++ * @param pThis the controller
++ */
++uint8_t MGC_HdrcServiceFunctionEp0(MGC_LinuxCd* pThis)
++{
++ uint16_t wCsrVal; /* */
++ uint16_t wCount; /* bytes available */
++ const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++ DBG(2, "<==\n");
++
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0); /* select ep0 */
++ wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0);
++ wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
++
++ DEBUG_CODE(4, { uint8_t myaddr=MGC_Read8(pBase, MGC_O_HDRC_FADDR); \
++ uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); \
++ printk(KERN_INFO "%s: wCrsVal=0x%x, wCount=%d, myaddr=%0x, mode=%s, ep0stage=%s\n", \
++ __FUNCTION__, wCsrVal, wCount, myaddr, decode_devctl(devctl), \
++ decode_ep0stage(pThis->bEnd0Stage) ); } );
++
++ /* I sent a stall.. need to acknowledge it now.. */
++ if(wCsrVal & MGC_M_CSR0_P_SENTSTALL) {
++ DBG(-1002, "acking stall while in ep0stage=%s\n",
++ decode_ep0stage(pThis->bEnd0Stage));
++
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ wCsrVal & ~MGC_M_CSR0_P_SENTSTALL );
++ pThis->bEnd0Stage=MGC_END0_STAGE_SETUP;
++ }
++
++ /* setup ended prematurely, abort it */
++ if (wCsrVal & MGC_M_CSR0_P_SETUPEND) {
++ DBG(-1002, "acking setupend while in ep0stage=%s\n",
++ decode_ep0stage(pThis->bEnd0Stage));
++
++ /* clearing it */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_CSR0_P_SVDSETUPEND );
++ pThis->bEnd0Stage=MGC_END0_STAGE_SETUP;
++ }
++
++ spin_unlock(&pThis->Lock);
++
++ /* handle completition interrupt */
++ if ( !wCsrVal && !wCount ) {
++ handle_ep0_completition_irq();
++ return TRUE;
++ }
++
++ switch( pThis->bEnd0Stage ) {
++ /* done transmitting */
++ case MGC_END0_STAGE_STATUSOUT:
++ case MGC_END0_STAGE_STATUSIN:
++ mgc_complete_ep0_request();
++ break;
++ }
++
++ switch( pThis->bEnd0Stage ) {
++ /* im alrewady writing to host, TX state,
++ * sequence #1 initiated during the setup
++ */
++ case MGC_END0_STAGE_TX:
++ if ( wCsrVal & MGC_M_CSR0_TXPKTRDY ) {
++ DBG(-1001, "MGC_END0_STAGE_TX\n");
++ ep0_txstate();
++ } break;
++
++ /* im alrewady receiving from host, RX state,
++ * sequence #2 initiated during the setup
++ */
++ case MGC_END0_STAGE_RX:
++ if ( wCsrVal & MGC_M_CSR0_RXPKTRDY ) {
++ DBG(-1001, "MGC_END0_STAGE_RX\n");
++ ep0_rxstate();
++ }
++ break;
++
++ /* received from host, RX State, header */
++ case MGC_END0_STAGE_SETUP:
++ if ( wCsrVal & MGC_M_CSR0_RXPKTRDY ) {
++ int count=0, handled=0;
++
++ count=MGC_ReadUSBControlRequest(pThis, wCount);
++ if ( count<0 ) {
++ /* ack the request */
++ ERR("error reading the control request: this is bad (tm)\n");
++ } else if ( 0==count ) { /* I got the full packet, GREAT! */
++ struct usb_ctrlrequest *pControlRequest=(struct usb_ctrlrequest*)
++ pThis->pEnd0Buffer;
++
++ DBG(-1002, "%s\n", decode_request(pControlRequest));
++
++ /* sequence #3 */
++ if ( is_zerodata_request(pControlRequest) ) {
++ uint16_t wCsrVal= MGC_M_CSR0_P_SVDRXPKTRDY
++ | MGC_M_CSR0_P_DATAEND;
++
++ pThis->bEnd0Stage = MGC_END0_STAGE_STATUSIN;
++ handled=service_zero_data_request(pThis,
++ pControlRequest);
++ if ( handled<0 && handled!=-EOPNOTSUPP ) {
++ wCsrVal |= MGC_M_CSR0_P_SENDSTALL;
++ }
++
++ /* ack the request */
++ DBG(3, "handled=%d, wCsrVal=%s, ep0stage=%s\n", handled,
++ decode_csr0(wCsrVal),
++ decode_ep0stage(pThis->bEnd0Stage) );
++
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
++ spin_unlock(&pThis->Lock);
++ } else {
++ /* sequence #1 */
++ if ( is_tx_request(pControlRequest) ) {
++ /* write to host, a request is posted on ep0 */
++ pThis->bEnd0Stage=MGC_END0_STAGE_TX;
++ handled=service_tx_request(pControlRequest);
++ /* sequence #2, a request is posted on ep0 */
++ } else if ( is_rx_request(pControlRequest) ) {
++ pThis->bEnd0Stage=MGC_END0_STAGE_RX;
++ handled=service_rx_request(pControlRequest);
++ }
++
++ if ( handled<0 ) {
++ /* stall it!!! application stall */
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_CSR0_P_SVDRXPKTRDY | MGC_M_CSR0_P_SENDSTALL);
++ spin_unlock(&pThis->Lock);
++ }
++ }
++
++ }
++ } else {
++
++ }
++ break;
++
++
++ /* handle the application stall on Ep0 */
++ default:
++ {
++ uint16_t wCsrVal = MGC_M_CSR0_P_SENDSTALL;
++
++ switch ( pThis->bEnd0Stage & ~MGC_END0_STAGE_STALL_BIT ) {
++
++ case MGC_END0_STAGE_TX:
++ wCsrVal|=MGC_M_CSR0_TXPKTRDY;
++ break;
++
++ case MGC_END0_STAGE_RX:
++ wCsrVal|=MGC_M_CSR0_RXPKTRDY;
++ break;
++
++ }
++
++ DBG(3, "Application stall from ep0stage=%s\n",
++ decode_ep0stage(pThis->bEnd0Stage));
++ spin_lock(&pThis->Lock);
++ MGC_SelectEnd(pBase, 0);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
++ spin_unlock(&pThis->Lock);
++
++ pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
++ }
++ break;
++ }
++
++ return 1;
++}
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/logx
+@@ -0,0 +1 @@
++make: *** No rule to make target `vmlinux'. Stop.
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c
+@@ -0,0 +1,371 @@
+/*
-+ * drivers/spi/spi-nomadik.c
-+ *
-+ * Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
++ * linux/drivers/usb/nomadik/musb_bus_direct.c
+ *
-+ * Author: Sachin Verma <sachin.verma@st.com>
-+ * Vaibhav Agarwal <vaibhav.agarwal@st.com
-+ * Initial version inspired by:
-+ * linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
++ * Copyright 2007, STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/ioport.h>
-+#include <linux/errno.h>
-+#include <linux/platform_device.h>
-+#include <linux/amba/bus.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
+
++#include "musbdefs.h"
+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/delay.h>
+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/defs.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/spi.h>
-+#include <asm/arch/debug.h>
-+#include <asm/arch/ssp-spi.h>
-+#include <asm/arch/msp-spi.h>
-+#include <asm/arch/msp.h>
++#ifdef MUSB_BOARD_FILE
++#include CONFIG_USB_INVENTRA_MUSB_BOARD_FILE
++#else
++#include "board.h"
++#endif
+
-+/***************************************************************************/
++#ifndef MUSB_BOARD_DEFAULT_SIZE
++#define MUSB_DEFAULT_ADDRESS_SPACE_SIZE 0x00001000
++#endif
+
-+#define NMDK_SPI_NAME "NOMADIK_SPI"
++#ifdef MUSB_V26
++#include <linux/device.h>
++#endif
+
-+#ifndef SPI_DEBUG
-+#define SPI_DEBUG 0
++/****************************** sysfs stuff *****************************/
++
++#define kobj_to_direct_driver(obj) container_of(obj, struct device_driver, kobj)
++#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
++
++/**************************** instance vars *****************************/
++
++#ifndef MUSB_USE_HCD_DRIVER
++static int MGC_InstancesCount=0;
++static MGC_LinuxCd** MGC_DriverInstances;
+#endif
+
-+#define NMDK_DEBUG SPI_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX NMDK_SPI_NAME /* msg header represents this module */
-+#define NMDK_DBG KERN_ERR /* message level */
++void *g_pDevice;
++/********************* under 26 thigs changes a bit *************************/
+
-+/***************************************************************************/
++#ifdef MUSB_V26
++#if 1
++struct device MGC_ControllerDevice =
++{
+
-+#define FALSE (0)
-+#define TRUE (1)
++};
+
-+#define DO_NOT_QUEUE_DMA (0)
-+#define QUEUE_DMA (1)
++struct device_driver MGC_ControllerDriver=
++{
++ .name = "musb-hcd",
++};
++#endif
+
-+/*#######################################################################
-+ Queue State
-+#########################################################################
-+ */
-+#define QUEUE_RUNNING (0)
-+#define QUEUE_STOPPED (1)
++#ifndef MUSB_USE_HCD_DRIVER
+
-+/***************************************************************************/
-+static void print_dma_info(u32 xfer_type, struct chip_data *chip){
-+ nmdk_dbg("Rx Pipe : mode = %08x\n", chip->dma_info->rx_dma_info.mode);
-+ nmdk_dbg("Rx Pipe : config = %08x\n", chip->dma_info->rx_dma_info.config);
-+ nmdk_dbg("Rx Pipe : srcdevtype = %s\n", chip->dma_info->rx_dma_info.srcdevtype);
-+ nmdk_dbg("Rx Pipe : destdevtype = %s\n", chip->dma_info->rx_dma_info.destdevtype);
++static inline ssize_t
++store_new_id(struct device_driver *driver, const char *buf, size_t count);
+
-+ nmdk_dbg("Tx Pipe : mode = %08x\n", chip->dma_info->tx_dma_info.mode);
-+ nmdk_dbg("Tx Pipe : config = %08x\n", chip->dma_info->tx_dma_info.config);
-+ nmdk_dbg("Tx Pipe : srcdevtype = %s\n", chip->dma_info->tx_dma_info.srcdevtype);
-+ nmdk_dbg("Tx Pipe : destdevtype = %s\n", chip->dma_info->tx_dma_info.destdevtype);
-+}
-+/***************************************************************************/
++
++static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
++
++static ssize_t driver_count=0;
++
++/* probably we don't need to be a system device in this case */
++struct device MGC_ControllerDevice =
++{
++
++};
++
++struct device_driver MGC_ControllerDriver=
++{
++ .name = "musb-hcd",
++};
+
+/**
-+ * null_cs_control - Dummy chip select function
-+ * @command: select/delect the chip
++ * store_new_id
+ *
-+ * If no chip select function is provided by client this is used as dummy
-+ * chip select
++ * Adds a new dynamic device ID to this driver,
++ * and causes the driver to probe for all devices again.
+ */
-+void null_cs_control(u32 command)
++static inline ssize_t
++store_new_id(struct device_driver *driver, const char *buf, size_t count)
+{
-+ nmdk_dbg_ftrace();
-+ nmdk_dbg("::::Dummy chip select control\n");
++ return driver_count++;
+}
-+EXPORT_SYMBOL(null_cs_control);
+
-+void nomadik_spi_tasklet(unsigned long param)
++
++static ssize_t
++direct_driver_attr_store(struct kobject * kobj, struct attribute *attr,
++ const char *buf, size_t count)
+{
-+ struct driver_data *drv_data = (struct driver_data *)param;
-+ struct spi_message *msg = drv_data->cur_msg;
-+ struct spi_transfer *previous = NULL;
-+ /*DMA complete. schedule next xfer */
-+ /*DISABLE DMA, and flush FIFO of SPI Controller */
-+ drv_data->execute_cmd(drv_data, DISABLE_DMA);
-+ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
-+ msg->actual_length += drv_data->cur_transfer->len;
-+ if (drv_data->cur_transfer->cs_change)
-+ drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
-+ msg->state = next_transfer(drv_data);
-+ if (msg->state == ERROR_STATE)
-+ goto handle_dma_error;
-+ else if (msg->state == DONE_STATE) {
-+ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+ msg->status = 0;
-+ giveback(msg, drv_data);
-+ return ;
-+ }
-+ /* Delay if requested at end of transfer */
-+ else if (msg->state == RUNNING_STATE) {
-+ previous =
-+ list_entry(drv_data->cur_transfer->transfer_list.
-+ prev, struct spi_transfer,
-+ transfer_list);
-+ if (previous->delay_usecs)
-+ udelay(previous->delay_usecs);
-+ if (previous->cs_change)
-+ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+ } else goto handle_dma_error;
++ struct device_driver *driver = kobj_to_direct_driver(kobj);
++ struct driver_attribute *dattr = attr_to_driver_attribute(attr);
++ ssize_t ret = 0;
+
-+ if (drv_data->cur_transfer->tx_dma) {
-+ atomic_inc(&drv_data->dma_cnt);
-+ __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach, (dma_addr_t) (drv_data->cur_transfer->tx_dma));
-+ __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
-+ (dma_addr_t) (drv_data->master_info->dma_srcaddr));
-+ set_dma_count(drv_data->cur_chip->dma_info->tx_dmach, (drv_data->cur_transfer->len));
-+ enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
-+ }
-+ if (drv_data->cur_transfer->rx_dma) {
-+ atomic_inc(&drv_data->dma_cnt);
-+ __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
-+ (dma_addr_t) (drv_data->master_info->dma_destaddr));
-+ __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach, (dma_addr_t) (drv_data->cur_transfer->rx_dma));
-+ set_dma_count(drv_data->cur_chip->dma_info->rx_dmach, (drv_data->cur_transfer->len));
-+ enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
++ if (get_driver(driver)) {
++ if (dattr->store)
++ ret = dattr->store(driver, buf, count);
++ put_driver(driver);
+ }
-+ /*Enable DMA for this chip */
-+ drv_data->execute_cmd(drv_data, ENABLE_DMA);
-+ return ;
-+
-+ handle_dma_error:
-+ atomic_set(&drv_data->dma_cnt, 0);
-+ drv_data->execute_cmd(drv_data, DISABLE_DMA);
-+ msg->status = -EIO;
-+ giveback(msg, drv_data);
-+ return ;
++ return ret;
+}
-+EXPORT_SYMBOL(nomadik_spi_tasklet);
+
-+/**
-+ * spi_dma_callback_handler - This function is invoked when dma xfer is complete
-+ * @param: context data which is drivers private data
-+ * @event: Status of current DMA transfer
-+ *
-+ * This function checks if DMA transfer is complete for current transfer
-+ * It fills the Rx Tx buffer pointers again and launch dma for next
-+ * transfer from this callback handler itself
-+ *
-+ */
-+irqreturn_t spi_dma_callback_handler(int irq, void *param)
++static ssize_t
++direct_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
+{
-+ struct driver_data *drv_data = (struct driver_data *)param;
-+ int flag = 0;
-+
-+ nmdk_dbg_ftrace();
++ struct device_driver *driver = kobj_to_direct_driver(kobj);
++ struct driver_attribute *dattr = attr_to_driver_attribute(attr);
++ ssize_t ret = 0;
+
-+ smp_mb();
-+ if (atomic_dec_and_test(&drv_data->dma_cnt)) {
-+ flag = 1;
-+ }
-+ smp_mb();
-+ if (flag == 1) {
-+ tasklet_schedule(&drv_data->spi_dma_tasklet);
++ if ( get_driver(driver) ) {
++ if (dattr->show)
++ ret = dattr->show(driver, buf);
++ put_driver(driver);
+ }
-+ return IRQ_HANDLED;
++ return ret;
+}
-+EXPORT_SYMBOL(spi_dma_callback_handler);
+
-+/**
-+ * giveback - current spi_message is over, schedule next spi_message and call callback of this msg
-+ * @message: current SPI message
-+ * @drv_data: spi driver private data structure
-+ *
-+ */
-+void giveback(struct spi_message *message, struct driver_data *drv_data)
++static struct sysfs_ops direct_driver_sysfs_ops = {
++ .show = direct_driver_attr_show,
++ .store = direct_driver_attr_store,
++};
++static struct kobj_type direct_driver_kobj_type = {
++ .sysfs_ops = &direct_driver_sysfs_ops,
++};
++
++static int
++direct_create_newid_file(struct device_driver *drv)
+{
-+ struct spi_transfer *last_transfer;
-+ unsigned long flags;
-+ struct spi_message *msg;
-+ void (*curr_cs_control) (u32 command);
++ int error = 0;
++ if (drv->probe != NULL)
++ error = sysfs_create_file(&drv->kobj,
++ &driver_attr_new_id.attr);
++ return error;
++}
+
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+ msg = drv_data->cur_msg;
++static int
++direct_populate_driver_dir(struct device_driver *drv)
++{
++ return direct_create_newid_file(drv);
++}
+
-+ curr_cs_control = drv_data->cur_chip->cs_control;
-+ drv_data->cur_msg = NULL;
-+ drv_data->cur_transfer = NULL;
-+ drv_data->cur_chip = NULL;
-+#ifdef SPI_WORKQUEUE
-+ queue_work(drv_data->workqueue, &drv_data->spi_work);
-+#endif
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+
-+ schedule_work(&drv_data->spi_work);
++/* ------------------------ let the ball rolling -------------------------*/
+
-+ last_transfer = list_entry(msg->transfers.prev,
-+ struct spi_transfer, transfer_list);
-+ if (!last_transfer->cs_change)
-+ curr_cs_control(SPI_CHIP_DESELECT);
-+ msg->state = NULL;
-+ if (msg->complete)
-+ msg->complete(msg->context);
-+ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++/* customize for different behavior */
++static int direct_hotplug (struct device *dev, char **envp, int num_envp,
++ char *buffer, int buffer_size)
++{
++ return -ENODEV;
+}
-+EXPORT_SYMBOL(giveback);
+
-+/**
-+ * next_transfer - Move to the Next transfer in the current spi message
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function moves though the linked list of spi transfers in the
-+ * current spi message and returns with the state of current spi
-+ * message i.e whether its last transfer is done(DONE_STATE) or
-+ * Next transfer is ready(RUNNING_STATE)
-+ */
-+void *next_transfer(struct driver_data *drv_data)
++static int direct_device_suspend(struct device * dev, u32 state)
+{
-+ struct spi_message *msg = drv_data->cur_msg;
-+ struct spi_transfer *trans = drv_data->cur_transfer;
-+ /* Move to next transfer */
-+ if (trans->transfer_list.next != &msg->transfers) {
-+ drv_data->cur_transfer =
-+ list_entry(trans->transfer_list.next,
-+ struct spi_transfer, transfer_list);
-+ return RUNNING_STATE;
-+ }
-+ return DONE_STATE;
++ return 0;
+}
-+EXPORT_SYMBOL(next_transfer);
+
-+/**
-+ * ssp_null_writer - To Write Dummy Data in Data register
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function is set as a write function for transfer which have
-+ * Tx transfer buffer as NULL. It simply writes '0' in the Data
-+ * register
-+ */
-+static void ssp_null_writer(struct driver_data *drv_data)
++/* customize for different behavior */
++static int direct_device_resume(struct device * dev)
+{
-+ while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF)
-+ && (drv_data->tx < drv_data->tx_end)) {
-+ /*Write '0' Data to Data Register */
-+ writel(0x0, SSP_DR(drv_data->regs));
-+ drv_data->tx += (drv_data->cur_chip->n_bytes);
-+ }
++ return 0;
+}
+
-+/**
-+ * ssp_null_reader - To read data from Data register and discard it
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function is set as a reader function for transfer which have
-+ * Rx Transfer buffer as null. Read Data is rejected
-+ *
-+ */
-+static void ssp_null_reader(struct driver_data *drv_data)
-+{
-+ while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE)
-+ && (drv_data->rx < drv_data->rx_end)) {
-+ readl(SSP_DR(drv_data->regs));
-+ drv_data->rx += (drv_data->cur_chip->n_bytes);
-+ }
++static int direct_bus_match(struct device * dev, struct device_driver * drv) {
++ return (&MGC_ControllerDriver==drv)?1:0;
+}
+
++struct bus_type direct_bus_type = {
++ .name = "system",
++ .match = direct_bus_match,
++ .hotplug = direct_hotplug,
++ .suspend = direct_device_suspend,
++ .resume = direct_device_resume,
++};
++
+/**
-+ * msp_null_writer - To Write Dummy Data in Data register
-+ * @drv_data: spi driver private data structure
++ * direct_register_driver - register a new driver
++ * @drv: the driver structure to register
+ *
-+ * This function is set as a write function for transfer which have
-+ * Tx transfer buffer as NULL. It simply writes '0' in the Data
-+ * register
++ * Adds the driver structure to the list of registered drivers
++ * Returns the number of devices which were claimed by the driver
++ * during registration. The driver remains registered even if the
++ * return value is zero.
+ */
-+static void msp_null_writer(struct driver_data *drv_data)
++static int
++direct_register_driver(struct device_driver *drv, struct bus_type *btype)
+{
-+ u32 cur_write = 0;
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
-+ if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+ return;
-+ writel( 0x0, MSP_DR(drv_data->regs));
-+ drv_data->tx += (drv_data->cur_chip->n_bytes);
-+ cur_write ++;
-+ if(cur_write == 8)
-+ return;
-+ }
++ int count = 0;
++
++ /* initialize common driver fields */
++ drv->bus = (btype)?btype:&direct_bus_type;
++ drv->kobj.ktype = &direct_driver_kobj_type;
++
++ /* register with core */
++ count = driver_register( drv );
++ if (count >= 0) {
++ direct_populate_driver_dir( drv );
++ }
++
++ return count ? count : 1;
+}
+
+/**
-+ * msp_null_reader - To read data from Data register and discard it
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function is set as a reader function for transfer which have
-+ * Rx Transfer buffer as null. Read Data is rejected
++ * unregister_driver - unregister a driver
++ * @drv: the driver structure to unregister
+ *
++ * Deletes the driver structure from the list of registered drivers,
++ * gives it a chance to clean up by calling its remove() function for
++ * each device it was responsible for, and marks those devices as
++ * driverless.
+ */
-+static void msp_null_reader(struct driver_data *drv_data)
++
++static void
++direct_unregister_driver(struct device_driver *drv)
+{
-+ u32 status;
-+ while(1){
-+ status = readl(MSP_FLR(drv_data->regs));
-+ if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+ return;
-+ readl(MSP_DR(drv_data->regs));
-+ drv_data->rx += (drv_data->cur_chip->n_bytes);
-+ }
++ driver_unregister( drv );
+}
+
++#endif
++#endif
++
++/* ------------------------------------------------------------------- */
++/* ------------------------------------------------------------------- */
++/* ------------------------------------------------------------------- */
++
++#ifdef MUSB_CUSTOM_DIRECT_BUS_FILE
++#include MUSB_CUSTOM_DIRECT_BUS_FILE
++#else
+/**
-+ * pump_transfers - Tasklet function which schedules next interrupt xfer
-+ * @data: spi driver private data structure
-+ *
++ * Discover and initialize the drivers on the direct bus.
+ */
-+static void pump_transfers(unsigned long data)
-+{
-+ struct driver_data *drv_data = (struct driver_data *)data;
-+ struct spi_message *message = NULL;
-+ struct spi_transfer *transfer = NULL;
-+ struct spi_transfer *previous = NULL;
-+
-+ nmdk_dbg_ftrace();
++int
++direct_bus_init(void) {
+
-+ message = drv_data->cur_msg;
-+ /* Handle for abort */
-+ if (message->state == ERROR_STATE) {
-+ message->status = -EIO;
-+ giveback(message, drv_data);
-+ return;
-+ }
-+ /* Handle end of message */
-+ if (message->state == DONE_STATE) {
-+ message->status = 0;
-+ giveback(message, drv_data);
-+ return;
++ int rc= -1;
++ char name[32];
++ void* pDevice = NULL;
++
++#ifdef MUSB_USE_HCD_DRIVER
++ MGC_LinuxCd* pThis;
++
++ /* already initialized */
++ if ( MGC_nIndex ) {
++ return 0;
+ }
-+ transfer = drv_data->cur_transfer;
-+ /* Delay if requested at end of transfer */
-+ if (message->state == RUNNING_STATE) {
-+ previous =
-+ list_entry(transfer->transfer_list.prev,
-+ struct spi_transfer, transfer_list);
-+ if (previous->delay_usecs)
-+ udelay(previous->delay_usecs);
-+ if (previous->cs_change)
-+ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+ } else {
-+ /* START_STATE */
-+ message->state = RUNNING_STATE;
++ snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
++
++ pDevice = &MGC_ControllerDevice;
++ g_pDevice=pDevice;
++ kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
++
++ rc = kobject_register(&((struct device*)pDevice)->kobj);
++
++ if(rc < 0){
++ ERR("failed to register:%d\n", rc);
++ return rc;
+ }
-+ drv_data->tx = (void *)transfer->tx_buf;
-+ drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
-+ drv_data->rx = (void *)transfer->rx_buf;
-+ drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
+
-+ if(drv_data->master->bus_num == SSP_CONTROLLER){
-+ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
-+ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++ INIT_LIST_HEAD( (struct list_head*)&((struct device*)pDevice)->klist_children );
++
++ ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
++
++ sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);
++
++ pThis = MGC_LinuxInitController(pDevice, MUSB_CONTROLLER_HDRC, INT_USBOTG,
++ ioremap(NOMADIK_USB_BASE, 0x100000), 0x00100000, name);
++
++ if(pThis) {
++ DBG(3, "MGC_LinuxInitController success MGC_struct:0x%p \n", pThis);
++ rc = 0;
++ MGC_VirtualHubStart( &(pThis->RootHub) );
+ }
-+ else{
-+ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
-+ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++ return(rc);
++
++#else
++ const int nCount = sizeof(MUSB_aLinuxController)
++ / sizeof(MUSB_LinuxController);
++ int nIndex;
++
++ INFO("Probing direct bus [direct=%d]\n", nCount);
++
++ if ( !nCount ) {
++ return 0;
++ }
++
++ KMALLOC(MGC_DriverInstances, nCount*sizeof(MGC_LinuxCd*), GFP_ATOMIC);
++ if ( !MGC_DriverInstances ) {
++ return -ENOMEM;
++ }
++
++#ifdef MUSB_V26
++ pDevice = &MGC_ControllerDevice;
++ kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
++ rc = kobject_register(&((struct device*)pDevice)->kobj);
++ if(rc < 0){
++ ERR("failed to register:%d\n", rc);
++ return rc;
+ }
+
-+ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
-+ drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
++ INIT_LIST_HEAD( &((struct device*)pDevice)->children );
++
++ ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
++ sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);
++ bus_register( &direct_bus_type );
++ direct_register_driver(&MGC_ControllerDriver, NULL);
++#endif
++
++ /* NON PCI machines */
++ for (nIndex = 0; !rc && nIndex < nCount; nIndex++) {
++ MUSB_LinuxController* pStaticController=&(MUSB_aLinuxController[nIndex]);
++
++ snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
++ MGC_DriverInstances[nIndex]=MGC_LinuxInitController(pDevice,
++ pStaticController->wType, pStaticController->dwIrq,
++ pStaticController->pBase,
++ (pStaticController->dwSize)? pStaticController->dwSize
++ : MUSB_DEFAULT_ADDRESS_SPACE_SIZE, name);
++
++ if( MGC_DriverInstances[nIndex] ) {
++#ifdef MUSB_VIRTHUB
++ MGC_VirtualHubStart( &(MGC_DriverInstances[nIndex]->RootHub) );
++#endif
++ MGC_InstancesCount++;
++ } else {
++ ERR("controller %d failed to initialize\n", nIndex);
++ direct_bus_shutdown();
++ rc=-1;
++ }
++ }
++ return MGC_InstancesCount;
++#endif
++
+}
+
+/**
-+ * do_dma_transfer - It handles transfers of the current message if it is DMA xfer
-+ * @data: spi driver's private data structure
-+ *
-+ *
+ *
+ */
-+static void do_dma_transfer(void *data)
++void direct_bus_shutdown(void)
+{
-+ struct driver_data *drv_data = (struct driver_data *)data;
++#ifdef MUSB_USE_HCD_DRIVER
++ kobject_unregister(&((struct device*)g_pDevice)->kobj); /* shoudl check the hcd drivers */
+
-+ atomic_set(&drv_data->dma_cnt, 0);
-+ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
+
-+ if ((drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_MEM) ||
-+ (drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_PERIPH)) {
-+ if (drv_data->cur_chip->dma_info->tx_dmach >= 0) {
-+ atomic_inc(&drv_data->dma_cnt);
-+ __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach,
-+ (dma_addr_t) (drv_data->cur_transfer->tx_dma));
-+ __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
-+ (dma_addr_t) (drv_data->master_info->dma_srcaddr));
-+ set_dma_count(drv_data->cur_chip->dma_info->tx_dmach,
-+ (drv_data->cur_transfer->len));
-+ enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
-+ }
-+ if (drv_data->cur_chip->dma_info->rx_dmach >= 0) {
-+ atomic_inc(&drv_data->dma_cnt);
-+ __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
-+ (dma_addr_t) (drv_data->master_info->dma_destaddr));
-+ __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach,
-+ (dma_addr_t) (drv_data->cur_transfer->rx_dma));
-+ set_dma_count(drv_data->cur_chip->dma_info->rx_dmach,
-+ (drv_data->cur_transfer->len));
-+ enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
-+ }
-+ if((drv_data->cur_chip->dma_info->tx_dma_info.mode & DMA_INFINITE_XFER) &&
-+ (drv_data->cur_chip->dma_info->rx_dma_info.mode & DMA_INFINITE_XFER)){
-+ /*Only if it is an infinite transfer, we will deploy mechanism to stop it*/
-+ nmdk_dbg("Only if it is an infinite transfer, we will deploy mechanism to stop it");
-+ drv_data->dma_ongoing = 1;
-+ }
-+ } else {
-+ nmdk_dbg(":::: Invalid DMA xfer type \n");
-+ goto err_dma_transfer;
-+ }
-+ /*Enable SPI Controller */
-+ drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
-+ return;
++#else
++ int nIndex=0;
+
-+ err_dma_transfer:
-+ drv_data->cur_msg->state = ERROR_STATE;
-+ drv_data->cur_msg->status = -EIO;
-+ giveback(drv_data->cur_msg, drv_data);
-+ return;
-+}
++ /* free the instances */
++ for (nIndex = 0; nIndex < MGC_InstancesCount; nIndex++) {
++ MGC_LinuxCdFree( MGC_DriverInstances[nIndex] );
++ }
+
-+static void do_interrupt_transfer(void *data)
-+{
-+ struct driver_data *drv_data = (struct driver_data *)data;
++ KFREE(MGC_DriverInstances);
++#ifdef MUSB_V26
++ direct_unregister_driver(&MGC_ControllerDriver);
++#endif
++#endif
+
-+ drv_data->tx = (void *)drv_data->cur_transfer->tx_buf;
-+ drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
-+ drv_data->rx = (void *)drv_data->cur_transfer->rx_buf;
-+ drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++}
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_cross.h
+@@ -0,0 +1,131 @@
++/*
++ * linux/drivers/usb/nomadik/musb_cross.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
+
-+ if(drv_data->master->bus_num == SSP_CONTROLLER){
-+ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
-+ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
-+ }
-+ else{
-+ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
-+ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
-+ }
++#ifndef __MUSB_CROSS_H
++#define __MUSB_CROSS_H
+
-+ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++#include <linux/version.h>
+
-+ drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
-+ drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
-+}
++/****************************** KERNEL VERSION MACROS ************************/
+
-+static void do_polling_transfer(void *data)
-+{
-+ struct driver_data *drv_data = (struct driver_data *)data;
-+ struct spi_message *message = NULL;
-+ struct spi_transfer *transfer = NULL;
-+ struct spi_transfer *previous = NULL;
-+ struct chip_data *chip;
-+ unsigned long limit = 0;
++#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
++#undef MUSB_V26
+
-+ chip = drv_data->cur_chip;
-+ message = drv_data->cur_msg;
++#ifndef MUSB_V24
++#define MUSB_V24
++#endif
+
-+ while (message->state != DONE_STATE) {
-+ /* Handle for abort */
-+ if (message->state == ERROR_STATE)
-+ break;
-+ transfer = drv_data->cur_transfer;
++#endif
+
-+ /* Delay if requested at end of transfer */
-+ if (message->state == RUNNING_STATE) {
-+ previous =
-+ list_entry(transfer->transfer_list.prev,
-+ struct spi_transfer, transfer_list);
-+ if (previous->delay_usecs)
-+ udelay(previous->delay_usecs);
-+ if (previous->cs_change)
-+ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+ } else {
-+ /* START_STATE */
-+ message->state = RUNNING_STATE;
-+ drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+ }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#undef MUSB_V24
++#ifndef MUSB_V26
++#define MUSB_V26
++#endif
++#endif
+
-+ /*Configuration Changing Per Transfer */
-+ drv_data->tx = (void *)transfer->tx_buf;
-+ drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
-+ drv_data->rx = (void *)transfer->rx_buf;
-+ drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
-+
-+ if(drv_data->master->bus_num == SSP_CONTROLLER){
-+ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
-+ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
-+ }
-+ else{
-+ drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
-+ drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
-+ }
++#ifdef MUSB_V26
+
-+ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
-+ drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
++#ifndef MUSB_V26_POST10
++#define MUSB_V26_POST10
++#endif
++#endif
+
-+ nmdk_dbg(":::: POLLING TRANSFER ONGOING ... \n");
-+ while (drv_data->tx < drv_data->tx_end) {
-+ drv_data->read(drv_data);
-+ drv_data->write(drv_data);
-+ }
-+
-+ limit = loops_per_jiffy << 1;
-+
-+ while ((drv_data->rx < drv_data->rx_end) && (limit--)){
-+ drv_data->read(drv_data);
-+ }
+
-+ /* Update total byte transfered */
-+ message->actual_length += drv_data->cur_transfer->len;
-+ if (drv_data->cur_transfer->cs_change)
-+ drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
-+ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+
-+ /* Move to next transfer */
-+ message->state = next_transfer(drv_data);
-+ }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
++#ifndef MUSB_USE_HCD_DRIVER
++#define MUSB_USE_HCD_DRIVER
++#endif
++#endif
+
-+ /* Handle end of message */
-+ if (message->state == DONE_STATE)
-+ message->status = 0;
-+ else
-+ message->status = -EIO;
++#endif
+
-+ giveback(message, drv_data);
-+ return;
-+}
-+/**
-+ * pump_messages - Workqueue function which processes spi message queue
-+ * @data: pointer to private data of spi driver
-+ *
-+ * This function checks if there is any spi message in the queue that
-+ * needs processing and delegate control to appropriate function
-+ * do_polling_transfer()/do_interrupt_transfer()/do_dma_transfer()
-+ * based on the kind of the transfer
-+ *
-+ */
-+static void pump_messages(struct work_struct *work)
-+{
-+ struct driver_data *drv_data = container_of(work, struct driver_data,spi_work);
-+ unsigned long flags;
+
-+ /* Lock queue and check for queue work */
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+ if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
-+ nmdk_dbg(":::: work_queue: Queue Empty\n");
-+ drv_data->busy = 0;
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return;
-+ }
-+ /* Make sure we are not already running a message */
-+ if (drv_data->cur_msg) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return;
-+ }
++/*********************************** WEIRDNESS ******************************/
+
-+ /* Extract head of queue */
-+ drv_data->cur_msg =
-+ list_entry(drv_data->queue.next, struct spi_message, queue);
++#ifdef MUSB_V26_POST10
++#define MUSB_MEMFLAG_TYPE unsigned int
++#else
++#define MUSB_MEMFLAG_TYPE int
++#endif
+
-+ list_del_init(&drv_data->cur_msg->queue);
-+ drv_data->busy = 1;
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
++/****************************** SYSTEM PROPERTIES ***************************/
+
-+ /* Initial message state */
-+ drv_data->cur_msg->state = START_STATE;
-+ drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
-+ struct spi_transfer, transfer_list);
++#if defined(MUSB_V26) || defined(MUSB_V24)
++#define MUSB_HAS_BUSNAME
++#endif
+
-+ /* Setup the SPI using the per chip configuration */
-+ drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
-+ drv_data->execute_cmd(drv_data, RESTORE_STATE);
-+ drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++#ifndef MUSB_LINUX_MV21
++#define HAS_USB_TT_MULTI
++#endif
+
-+ if (drv_data->cur_chip->xfer_type == POLLING_TRANSFER)
-+ do_polling_transfer(drv_data);
-+ else if (drv_data->cur_chip->xfer_type == INTERRUPT_TRANSFER)
-+ do_interrupt_transfer(drv_data);
-+ else /* DMA_TRANSFER*/
-+ do_dma_transfer(drv_data);
-+}
++#ifdef CONFIG_PREEMPT
++/* warning??? */
++#endif
+
-+int init_queue(struct driver_data *drv_data)
-+{
-+ INIT_LIST_HEAD(&drv_data->queue);
-+ spin_lock_init(&drv_data->lock);
++/* gstorage is liked to the driver: the init code lives there */
++#ifdef MUSB_GSTORAGE
++#define MUSB_SKIP_INIT
++#endif
+
-+ drv_data->run = QUEUE_STOPPED;
-+ drv_data->busy = 0;
++/* When compiled in the kernel, the init function is needed only when gadget
++ * gadget API is not compiled (usb_register_driver takes care of the init)
++ */
++#if defined(MUSB_BUILTIN) && !defined(MUSB_GADGET)
++#ifndef MUSB_SKIP_INIT
++#define MUSB_SKIP_INIT
++#endif
++#endif
+
-+ tasklet_init(&drv_data->pump_transfers, pump_transfers,
-+ (unsigned long)drv_data);
-+ INIT_WORK(&drv_data->spi_work, pump_messages);
-+#ifdef SPI_WORKQUEUE
-+ drv_data->workqueue = create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id);
-+ if (drv_data->workqueue == NULL)
-+ return -EBUSY;
-+#endif
-+ return 0;
-+}
-+EXPORT_SYMBOL(init_queue);
++/* -------------------------------- OTG ----------------------------- */
+
-+int start_queue(struct driver_data *drv_data)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+ if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return -EBUSY;
-+ }
-+ drv_data->run = QUEUE_RUNNING;
-+ drv_data->cur_msg = NULL;
-+ drv_data->cur_transfer = NULL;
-+ drv_data->cur_chip = NULL;
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ /*queue_work(drv_data->workqueue, &drv_data->pump_messages);*/
-+ /*schedule_work(&drv_data->spi_work);*/
-+ return 0;
-+}
-+EXPORT_SYMBOL(start_queue);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
++#define MUSB_HAS_OTG
++#define HAS_HNP_SUPPORT
++#endif
+
-+int stop_queue(struct driver_data *drv_data)
-+{
-+ unsigned long flags;
-+ unsigned limit = 500;
-+ int status = 0;
++/* -------------------------------- DMA ----------------------------- */
+
-+ spin_lock_irqsave(&drv_data->lock, flags);
++#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
-+ /* This is a bit lame, but is optimized for the common execution path.
-+ * A wait_queue on the drv_data->busy could be used, but then the common
-+ * execution path (pump_messages) would be required to call wake_up or
-+ * friends on every SPI message. Do this instead */
-+ drv_data->run = QUEUE_STOPPED;
-+ while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ msleep(10);
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+ }
-+ if (!list_empty(&drv_data->queue) || drv_data->busy)
-+ status = -EBUSY;
++/* MVL21 doesn't support DMA */
++#if defined(MUSB_LINUX_MV21)
++#ifdef MUSB_DMA
++#error "DMA Mode not supported in MontaVista 2.1"
++#endif
+
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
++/* DMA supported from 2.4 'till 2.6.10 */
++#elif defined(MUSB_V24) || (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
++#ifndef MUSB_HAS_DMA_URBS
++#define MUSB_HAS_DMA_URBS
++#endif
+
-+ return status;
-+}
-+EXPORT_SYMBOL(stop_queue);
++/* DMA not supported on versions >= 2.6.10 */
++#elif ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) )
+
-+int destroy_queue(struct driver_data *drv_data)
-+{
-+ int status;
-+ status = stop_queue(drv_data);
-+ if (status != 0)
-+ return status;
-+#ifdef SPI_WORKQUEUE
-+ destroy_workqueue(drv_data->workqueue);
-+#endif
-+ return 0;
-+}
-+EXPORT_SYMBOL(destroy_queue);
++#ifdef MUSB_DMA
++#error "DMA Mode MIGHT not be supported in kernels > 2.6.10"
++#endif
+
-+/**
-+ * nomadik_spi_transfer - transfer function registered to SPI master framework
-+ * @spi: spi device which is requesting transfer
-+ * @msg: spi message which is to handled is queued to driver queue
++#endif
++
++/* -------------------------------- GADGETS ----------------------------- */
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_debug.c
+@@ -0,0 +1,190 @@
++/*
++ * linux/drivers/usb/nomadik/musb_debug.c
+ *
-+ * This function is registered to the SPI framework for this SPI master
-+ * controller. It will queue the spi_message in the queue of driver if
-+ * the queue is not stopped and return.
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
-+int nomadik_spi_transfer(struct spi_device *spi, struct spi_message *msg)
-+{
-+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
-+ unsigned long flags;
+
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+ struct spi_master *master;
-+ int status = 0;
-+#endif
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/completion.h>
++#include <linux/interrupt.h>
+
-+ nmdk_dbg_ftrace();
++#include <linux/usb.h>
+
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+ master = drv_data->master;
-+ switch(master->bus_num) {
-+ case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user != SPI_USER_MSP) {
-+ status = -EINVAL;
-+ printk("MSP0 already in use in %d mode", drv_data->flag_msp0->user);
-+ }
-+ break;
-+ case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user != SPI_USER_MSP) {
-+ status = -EINVAL;
-+ printk("MSP1 already in use in %d mode", drv_data->flag_msp1->user);
-+ }
-+ break;
-+ case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user != SPI_USER_MSP) {
-+ status = -EINVAL;
-+ printk("MSP2 already in use in %d mode", drv_data->flag_msp2->user);
-+ }
-+ break;
-+ }
-+ if(status)
-+ return status;
-+#endif
-+ spin_lock_irqsave(&drv_data->lock, flags);
++#include "debug.h"
++#include "musbdefs.h"
+
-+
-+ if (drv_data->run == QUEUE_STOPPED) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return -ESHUTDOWN;
-+ }
-+ if(drv_data->dma_ongoing){
-+ struct chip_data *chip;
-+ chip = spi_get_ctldata(spi);
-+ nmdk_dbg(":::: Current chip(%p), Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip, chip->chip_id);
-+ nmdk_dbg(":::: Current chip Id (doing infinite DMA): %d -- Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip->chip_id, chip->chip_id);
-+ if(drv_data->cur_chip->chip_id != chip->chip_id){
-+ nmdk_dbg(":::: Chip_id are not same, Hence current DMA xfer not disabled \n");
-+ }
-+ else{
-+ nmdk_dbg(":::: Chip_id are same. Disabling current infinite DMA xfer\n");
-+
-+ drv_data->dma_ongoing = 0;
-+
-+ if (drv_data->cur_chip->dma_info->tx_dmach != -1) {
-+ free_dma(drv_data->cur_chip->dma_info->tx_dmach);
-+ drv_data->cur_chip->dma_info->tx_dmach = -1;
-+ }
-+ if (drv_data->cur_chip->dma_info->rx_dmach != -1) {
-+ free_dma(drv_data->cur_chip->dma_info->rx_dmach);
-+ drv_data->cur_chip->dma_info->rx_dmach = -1;
-+ }
-+ drv_data->execute_cmd(drv_data, DISABLE_DMA);
-+ drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+ drv_data->cur_msg = NULL;
-+ drv_data->cur_transfer = NULL;
-+ drv_data->cur_chip = NULL;
-+#ifdef SPI_WORKQUEUE
-+ queue_work(drv_data->workqueue, &drv_data->spi_work);
-+#else
-+ schedule_work(&drv_data->spi_work);
-+#endif
-+ }
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return 0;
-+ }
-+
-+ nmdk_dbg(":::: Regular request (No infinite DMA ongoing)\n");
-+
-+ msg->actual_length = 0;
-+ msg->status = -EINPROGRESS;
-+ msg->state = START_STATE;
++#define IPRINTF(_f, _m) printk(KERN_INFO "%s"_f, indent, _m)
++#define isspace(c) (c==' ' || c=='\t')
++#define LABEL KERN_INFO "dump: "
+
-+ list_add_tail(&msg->queue, &drv_data->queue);
-+ if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
-+#ifdef SPI_WORKQUEUE
-+ queue_work(drv_data->workqueue, &drv_data->spi_work);
-+#else
-+ schedule_work(&drv_data->spi_work);
-+#endif
++/******************************************************************/
+
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return 0;
++int MGC_DebugLevel=MUSB_DEBUG;
++int MGC_DebugDisable=0;
++
++/******************************************************************/
++
++/* Decode CSR0 value to a string. Not reentrant
++ */
++char *decode_csr0(uint16_t csr0) {
++ static char buf[64];
++ sprintf(buf, "(%s%s%s%s)",
++ csr0&MGC_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"",
++ csr0&MGC_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"",
++ csr0&MGC_M_CSR0_P_SENDSTALL ? "[stalled]":"",
++ csr0&MGC_M_CSR0_P_DATAEND ? "[dataend]":"");
++ return buf;
+}
-+EXPORT_SYMBOL(nomadik_spi_transfer);
+
-+int calculate_effective_freq(int freq, t_ssp_clock_params * clk_freq)
-+{
-+ /*Lets calculate the frequency parameters */
-+ uint32 cpsdvsr = 2;
-+ uint32 scr = 0;
-+ bool_t freq_found = FALSE;
-+ uint32 max_tclk;
-+ uint32 min_tclk;
-+
-+ nmdk_dbg_ftrace();
++/* Decode a value to binary.
++ */
++char *decode_bits(uint16_t value) {
++ int i=0;
++ static char buf[64];
+
-+ max_tclk = (NMDK_SSP_CLOCK_FREQ / (MIN_CPSDVR * (1 + MIN_SCR))); /* cpsdvscr = 2 & scr 0 */
-+ min_tclk = (NMDK_SSP_CLOCK_FREQ / (MAX_CPSDVR * (1 + MAX_SCR))); /* cpsdvsr = 254 & scr = 255 */
++ for (; i<16;i++) {
++ buf[15-i]=(value&(1<<i))?'1':'0';
++ }
+
-+ if ((freq <= max_tclk) && (freq >= min_tclk)) {
-+ while (cpsdvsr <= MAX_CPSDVR && !freq_found) {
-+ while (scr <= MAX_SCR && !freq_found) {
-+ if ((NMDK_SSP_CLOCK_FREQ /
-+ (cpsdvsr * (1 + scr))) > freq)
-+ scr += 1;
-+ else {
-+ /* This bool is made TRUE when effective frequency >= target frequency is found */
-+ freq_found = TRUE;
-+ if ((NMDK_SSP_CLOCK_FREQ /
-+ (cpsdvsr * (1 + scr))) != freq) {
-+ if (scr == MIN_SCR) {
-+ cpsdvsr -= 2;
-+ scr = MAX_SCR;
-+ } else
-+ scr -= 1;
-+ }
-+ }
-+ }
-+ if (!freq_found) {
-+ cpsdvsr += 2;
-+ scr = MIN_SCR;
-+ }
-+ }
-+ if (cpsdvsr != 0) {
-+ nmdk_dbg(":::: SSP Effective Frequency is %ld\n", (NMDK_SSP_CLOCK_FREQ / (cpsdvsr * (1 + scr))));
-+ clk_freq->cpsdvsr = (uint8) (cpsdvsr & 0xFF);
-+ clk_freq->scr = (uint8) (scr & 0xFF);
-+ nmdk_dbg(":::: SSP cpsdvsr = %d, scr = %d\n",
-+ clk_freq->cpsdvsr, clk_freq->scr);
-+ }
-+ } else {
-+ /*User is asking for out of range Freq. */
-+ nmdk_dbg(":::: setup - controller data is incorrect: Out of Range Frequency");
-+ return -EINVAL;
-+ }
-+ return 0;
++ return buf;
+}
-+EXPORT_SYMBOL(calculate_effective_freq);
+
-+/**
-+ * process_dma_info - Processes the DMA info provided by client drivers
-+ * @chip_info: chip info provided by client device
-+ * @chip: Runtime state maintained by the spi controller for each spi device
-+ *
-+ * This function processes and stores DMA config provided by client driver
-+ * into the runtime state maintained by the spi controller driver
++/* Decode TXCSR register.
+ */
-+int process_dma_info(struct nmdk_spi_config_chip *chip_info,
-+ struct chip_data *chip, void * data)
-+{
-+ struct driver_data *drv_data = (struct driver_data *)data;
++char *decode_txcsr(uint16_t txcsr) {
++ static char buf[256];
++ sprintf(buf, "%s (%s%s%s%s)",
++ decode_bits(txcsr),
++ txcsr&MGC_M_TXCSR_TXPKTRDY ? "[TXPKTRDY]":"",
++ txcsr&MGC_M_TXCSR_AUTOSET ? "[MGC_M_TXCSR_AUTOSET]":"",
++ txcsr&MGC_M_TXCSR_DMAENAB ? "[MGC_M_TXCSR_DMAENAB]":"",
++ txcsr&MGC_M_TXCSR_DMAMODE ? "[MGC_M_TXCSR_DMAMODE]":"");
++ return buf;
++}
+
-+ /* default setup required for any SPI dma transfer*/
-+ chip->dma_info->rx_dma_info.srcdevtype = drv_data->master_info->dma_srcdevtype;
-+ chip->dma_info->rx_dma_info.config = 0;
++/*
++ */
++char *decode_devctl(uint16_t devctl) {
++ return (devctl&MGC_M_DEVCTL_HM)?"host":"function";
++}
+
-+ chip->dma_info->tx_dma_info.destdevtype = drv_data->master_info->dma_destdevtype;
-+ chip->dma_info->tx_dma_info.config = 0;
-+
-+ if (chip_info->dma_xfer_type == SPI_WITH_MEM) {
-+ chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_MEM);
-+ chip->dma_info->rx_dma_info.destdevtype = "mem";
-+
-+ chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(MEM_TO_PERIPH);
-+ chip->dma_info->tx_dma_info.srcdevtype = "mem";
-+ if (chip_info->dma_config) {
-+ chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+ chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+ if (chip_info->dma_config->tx_client_dmadev_config) {
-+ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
-+ }
-+ if (chip_info->dma_config->rx_client_dmadev_config) {
-+ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
-+ }
-+ if (chip_info->dma_config->tx_master_dmadev_config) {
-+ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
-+ }
-+ if (chip_info->dma_config->rx_master_dmadev_config) {
-+ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
-+ }
-+ }
-+ } else { /*SPI_WITH_PERIPH*/
-+ chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
-+ chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
-+ if (chip_info->dma_config) {
-+ chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+ chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+ if (chip_info->dma_config->tx_client_dmadev_config) {
-+ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
-+ chip->dma_info->rx_dma_info.destdevtype = chip_info->dma_config->tx_client_dmadev_config->devtype;
-+ }
-+ if (chip_info->dma_config->rx_client_dmadev_config) {
-+ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
-+ chip->dma_info->tx_dma_info.srcdevtype = chip_info->dma_config->rx_client_dmadev_config->devtype;
-+ }
-+ if (chip_info->dma_config->tx_master_dmadev_config) {
-+ chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
-+ }
-+ if (chip_info->dma_config->rx_master_dmadev_config) {
-+ chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
-+ }
-+ } else return -EINVAL;
-+ }
+
-+ print_dma_info(chip_info->dma_xfer_type, chip);
-+ return 0;
++/*
++ */
++char *decode_ep0stage(uint8_t stage) {
++ static char buff[64];
++ uint8_t stallbit=stage&MGC_END0_STAGE_STALL_BIT;
++
++ stage=stage&~stage&MGC_END0_STAGE_STALL_BIT;
++ sprintf(buff, "%s%s", (stallbit)? "stall-" : "",
++ (stage==MGC_END0_STAGE_SETUP)
++ ? "setup" :
++ (stage==MGC_END0_STAGE_TX)
++ ? "tx" :
++ (stage==MGC_END0_STAGE_RX)
++ ? "rx" :
++ (stage==MGC_END0_STAGE_STATUSIN)
++ ? "statusin" :
++ (stage==MGC_END0_STAGE_STATUSOUT)
++ ? "statusout" : "error");
++ return buff;
+}
+
-+EXPORT_SYMBOL(process_dma_info);
+
-+/**
-+ * nomadik_spi_cleanup - cleanup function registered to SPI master framework
-+ * @spi: spi device which is requesting cleanup
-+ *
-+ * This function is registered to the SPI framework for this SPI master
-+ * controller. It will free the runtime state of chip.
++/*
+ */
-+void nomadik_spi_cleanup(const struct spi_device *spi)
++void dump_urb (void *pUrb)
+{
-+ struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
-+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
-+ struct spi_master *master;
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+ int status =0;
++ struct urb* purb=(struct urb*)pUrb;
++
++ printk (LABEL "urb :%p\n", purb);
++ printk (LABEL "urb_list :%s\n", dump_node(&purb->urb_list));
++#ifdef V24
++ printk (LABEL "next :%p\n", purb->next);
+#endif
-+ nmdk_dbg_ftrace();
++ printk (LABEL "dev :%p\n", purb->dev);
++ printk (LABEL "pipe :%08X\n", purb->pipe);
++ printk (LABEL "status :%d\n", purb->status);
++ printk (LABEL "transfer_flags :%08X\n", purb->transfer_flags);
++ printk (LABEL "transfer_buffer :%p\n", purb->transfer_buffer);
++ printk (LABEL "transfer_buffer_length:%d\n", purb->transfer_buffer_length);
++ printk (LABEL "actual_length :%d\n", purb->actual_length);
++ printk (LABEL "setup_packet :%p\n", purb->setup_packet);
++ printk (LABEL "start_frame :%d\n", purb->start_frame);
++ printk (LABEL "number_of_packets :%d\n", purb->number_of_packets);
++ printk (LABEL "interval :%d\n", purb->interval);
++ printk (LABEL "error_count :%d\n", purb->error_count);
++ printk (LABEL "context :%p\n", purb->context);
++ printk (LABEL "complete :%p\n", purb->complete);
++}
+
-+ master = drv_data->master;
++/**
++ * Dump core registers whose reads are non-destructive.
++ * @param pThis
++ * @param bEnd
++ */
++void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd)
++{
++ MGC_SelectEnd(pBase, bEnd);
+
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+ switch(master->bus_num) {
-+ case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user == SPI_USER_MSP) {
-+ down(&drv_data->flag_msp0->lock);
-+ drv_data->flag_msp0->user = SPI_NO_MSP_USER;
-+ up(&drv_data->flag_msp0->lock);
-+ nmdk_dbg("Flag cleanup for MSP0\n");
-+ }
-+ else {
-+ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", (drv_data->flag_msp0->user));
-+ status = -EFAULT;
-+ }
-+ break;
-+ case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user == SPI_USER_MSP) {
-+ down(&drv_data->flag_msp1->lock);
-+ drv_data->flag_msp1->user = SPI_NO_MSP_USER;
-+ up(&drv_data->flag_msp1->lock);
-+ nmdk_dbg("Flag cleanup for MSP1\n");
-+ }
-+ else {
-+ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
-+ status = -EFAULT;
-+ }
-+ break;
-+ case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user == SPI_USER_MSP) {
-+ down(&drv_data->flag_msp2->lock);
-+ drv_data->flag_msp2->user = SPI_NO_MSP_USER;
-+ up(&drv_data->flag_msp2->lock);
-+ nmdk_dbg("Flag cleanup for MSP2\n");
-+ }
-+ else {
-+ printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
-+ status = -EFAULT;
-+ }
-+ break;
-+ }
-+ if(status)
-+ return ;
-+#endif
-+ if((master->bus_num == MSP_0_CONTROLLER) ||(master->bus_num == MSP_1_CONTROLLER) || (master->bus_num == MSP_2_CONTROLLER)) {
-+ nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
-+ free_irq(drv_data->adev->irq[0], drv_data);
-+ }
-+ if (chip){
-+ if(chip->dma_info) {
-+ if (chip->dma_info->tx_dmach != -1) {
-+ free_dma(chip->dma_info->tx_dmach);
-+ chip->dma_info->tx_dmach = -1;
-+ }
-+ if (chip->dma_info->rx_dmach != -1) {
-+ free_dma(chip->dma_info->rx_dmach);
-+ chip->dma_info->rx_dmach = -1;
-+ }
-+ kfree(chip->dma_info);
-+ }
-+ kfree(chip);
-+ }
++ if(!bEnd) {
++ printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n",
++ MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_TYPE0, 0),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0));
++ } else {
++ printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n",
++ bEnd,
++ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
++ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd));
++ printk(KERN_INFO " RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n",
++ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
++ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
++ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd),
++ MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd));
++ }
++
++ if( multipoint) {
++ printk(KERN_INFO " TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n",
++ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR)),
++ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR)),
++ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT)));
++ printk(KERN_INFO " RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n",
++ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR)),
++ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR)),
++ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT)));
++ }
+}
-+EXPORT_SYMBOL(nomadik_spi_cleanup);
+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Sachin Verma <sachin.verma@st.com> : Vaibhav Agarwal <vaibhav.agarwal@st.com");
-+MODULE_DESCRIPTION("Nomadik SPI driver");
-diff -Nauprw linux-2.6.20/drivers/usb/gadget/file_storage.c ../new/linux-2.6.20/drivers/usb/gadget/file_storage.c
---- linux-2.6.20/drivers/usb/gadget/file_storage.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/gadget/file_storage.c 2008-08-08 19:15:19.000000000 +0530
-@@ -272,12 +272,11 @@ MODULE_DESCRIPTION(DRIVER_DESC);
- MODULE_AUTHOR("Alan Stern");
- MODULE_LICENSE("Dual BSD/GPL");
-
--/* Thanks to NetChip Technologies for donating this product ID.
-- *
-- * DO NOT REUSE THESE IDs with any other driver!! Ever!!
-- * Instead: allocate your own, using normal USB-IF procedures. */
--#define DRIVER_VENDOR_ID 0x0525 // NetChip
--#define DRIVER_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget
++
++/* list related */
++
+/*
-+ * Replaced with ST ID
++ * NOT REENTRANT!
+ */
-+#define DRIVER_VENDOR_ID 0x0483 // ST ID
-+#define DRIVER_PRODUCT_ID 0x8815 // 0xa4a5 Linux-USB File-backed Storage Gadget
-
-
- /*
-@@ -373,7 +372,7 @@ static struct {
- .transport_parm = "BBB",
- .protocol_parm = "SCSI",
- .removable = 0,
-- .can_stall = 1,
-+ .can_stall = 0, /* for nhk15 */
- .vendor = DRIVER_VENDOR_ID,
- .product = DRIVER_PRODUCT_ID,
- .release = 0xffff, // Use controller chip type
-@@ -3860,7 +3859,7 @@ static int __init fsg_bind(struct usb_ga
- goto out;
-
- if (mod_data.removable) { // Enable the store_xxx attributes
-- dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
-+ dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0777; /*NHK15*/
- dev_attr_ro.store = store_ro;
- dev_attr_file.store = store_file;
- }
-diff -Nauprw linux-2.6.20/drivers/usb/Kconfig ../new/linux-2.6.20/drivers/usb/Kconfig
---- linux-2.6.20/drivers/usb/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/Kconfig 2008-07-04 23:45:22.000000000 +0530
-@@ -133,5 +133,7 @@ source "drivers/usb/atm/Kconfig"
-
- source "drivers/usb/gadget/Kconfig"
-
-+source "drivers/usb/nomadik/Kconfig"
++char *dump_node(struct list_head *node) {
++ static char buf[64];
++ sprintf(buf, "[n=%p,p=%p]", node->next, node->prev);
++ return buf;
++}
+
- endmenu
-
-diff -Nauprw linux-2.6.20/drivers/usb/Makefile ../new/linux-2.6.20/drivers/usb/Makefile
---- linux-2.6.20/drivers/usb/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/Makefile 2008-07-04 23:45:23.000000000 +0530
-@@ -67,6 +67,7 @@ obj-$(CONFIG_USB_SISUSBVGA) += misc/
- obj-$(CONFIG_USB_TEST) += misc/
- obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/
- obj-$(CONFIG_USB_USS720) += misc/
-+obj-y += nomadik/
-
- obj-$(CONFIG_USB_ATM) += atm/
- obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/board.h ../new/linux-2.6.20/drivers/usb/nomadik/board.h
---- linux-2.6.20/drivers/usb/nomadik/board.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/board.h 2008-07-28 15:20:49.000000000 +0530
-@@ -0,0 +1,58 @@
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h
+@@ -0,0 +1,48 @@
+/*
-+ * linux/drivers/usb/nomadik/board.h
++ * linux/drivers/usb/nomadik/musb_epdescriptors.h
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] = {
+
-+/*
-+ * Example board-specific definitions.
-+ * $Revision: 1.6 $
-+ *
-+ * It is suggested to:
-+ * 1. Copy this file to one named after your target:
-+ * cp board.h board-mytarget.h
-+ * 2. Save this file for future reference:
-+ * mv board.h board-example.h
-+ * 3. Link board.h to yours:
-+ * ln -s board-mytarget.h board.h
-+ * 4. Edit yours, providing, for each controller:
-+ * - controller type (MUSB_CONTROLLER_HDRC or MUSB_CONTROLLER_MHDRC)
-+ * - physical base address in kernel space
-+ * - interrupt number (interpretation is platform-specific)
-+ */
++{}, /* EP0 use the default */
++{ MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
++{ MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 },
++{ MUSB_EPD_T_INTR, MUSB_EPD_D_RX, 512 }
++};
+
-+/** Array of information about hard-wired controllers
-+ * This will be liked to the first module that includes this file.
-+ */
++/**
++struct MGC_EpFifoDescriptor {
++ uint8_t bType; 0 for autoconfig, CNTR, ISOC, BULK, INTR
++ uint8_t bDir; 0 for autoconfig, INOUT, IN, OUT
++ uint16_t wSize; 0 for autoconfig, or the size
++ uint 8_t bDbe; double buffering 0 disabled, 1 enabled
++};
+
-+#ifndef __MUSB_LINUX_BOARD_H__
-+#define __MUSB_LINUX_BOARD_H__
-+#include <asm/arch/soc_devices.h>
++#define MUSB_EPD_AUTOCONFIG 0
+
-+#include <asm/arch/irqs.h>
-+#define INT_USBOTG IRQ_USBOTG
++#define MUSB_EPD_T_CNTRL 1
++#define MUSB_EPD_T_ISOC 2
++#define MUSB_EPD_T_BULK 3
++#define MUSB_EPD_T_INTR 4
+
-+MUSB_LinuxController MUSB_aLinuxController[] =
-+{
-+ { MUSB_CONTROLLER_HDRC, (void*)NOMADIK_USB_BASE, INT_USBOTG }
-+ /*
-+ { MUSB_CONTROLLER_HDRC, (void*)0xc0000000, 9 }
-+ */
-+};
++#define MUSB_EPD_D_INOUT 0
++#define MUSB_EPD_D_TX 1
++#define MUSB_EPD_D_RX 2
++*/
+
-+#endif /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/debug.h ../new/linux-2.6.20/drivers/usb/nomadik/debug.h
---- linux-2.6.20/drivers/usb/nomadik/debug.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/debug.h 2008-07-28 15:20:49.000000000 +0530
-@@ -0,0 +1,104 @@
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c
+@@ -0,0 +1,429 @@
+/*
-+ * linux/drivers/usb/nomadik/debug.h
++ * linux/drivers/usb/nomadik/musb_epfifocfg.c
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#ifndef __MUSB_LINUX_DEBUG_H__
-+#define __MUSB_LINUX_DEBUG_H__
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
+
-+/*
-+ * Linux HCD (Host Controller Driver) for HDRC and/or MHDRC.
-+ * Debug support routines
++#include "musbdefs.h"
++#include "musb_epdescriptors.h"
++
++#ifdef MUSB_EPFIFOCONFIG_FILE
++#include CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
++#endif
++
++#define DYN_FIFO_SIZE (1<<(MUSB_C_RAM_BITS+2))
++#define CONFIGURE_FIFO(_pThis, _pEnd, _Dsc, _wFifoOffset) \
++ configure_fifo(_pThis, _pEnd, (_Dsc)->bDir, (_Dsc)->wSize, (_Dsc)->bDbe, _wFifoOffset)
++
++
++/* force array based */
++#ifdef MUSB_C_DYNFIFO_DEF
++
++#ifdef MUSB_EPDISCRIPTORS_FILE
++/**
++ * configure the fifo and make sure the pThis endmask is updated.
+ *
++ * @param pThis
++ * @param pEnd the end to configure
++ * @param bDir the direction (in, out, inout)
++ * @param wSize the fifo size, real fifo size
++ * @param bDbe double buffering enabled?
++ * @param wFifoOffset the current offset
++ */
++static uint16_t configure_fifo(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd,
++ uint8_t bDir, uint16_t wSize, uint8_t bDbe, uint16_t wFifoOffset)
++{
++ uint16_t offset=wSize;
++ void* pBase = pThis->pRegs;
++ uint8_t szValue=wSize>>3;
++ uint16_t addValue=wFifoOffset>>3;
++
++ /* when double buffering is enabled endpoint needs twice the size */
++ if (bDbe) {
++ szValue |= (1<<4);
++ offset*=2;
++ }
++
++ /* configure the FIFO */
++ MGC_SelectEnd(pBase, pEnd->bEnd);
++ switch ( bDir ) {
++ case MUSB_EPD_D_TX:
++ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 0x6);
++ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 64 >> 3);
++
++ pEnd->wMaxPacketSizeTx = wSize;
++ pEnd->wMaxPacketSizeRx = 0;
++ pEnd->bIsSharedFifo = FALSE;
++ break;
++ case MUSB_EPD_D_RX:
++ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 0x6);
++ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, (64 + 512 ) >> 3);
++
++ pEnd->wMaxPacketSizeTx = 0;
++ pEnd->wMaxPacketSizeRx = wSize;
++ pEnd->bIsSharedFifo = FALSE;
++ break;
++ case MUSB_EPD_D_INOUT:
++ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, szValue);
++ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, addValue);
++
++ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, szValue);
++ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, addValue);
++
++ pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=wSize;
++ pEnd->bIsSharedFifo = TRUE;
++ break;
++
++ default:
++ ERR("direction %d not supported\n", bDir);
++ offset=0;
++ break;
++ }
++
++ /* make sure the endmask is right */
++ if ( offset ) {
++ pThis->wEndMask |= (1 << pEnd->bEnd);
++ }
++
++ /* TODO: flush the FIFO after an ep size change */
++
++
++ return offset;
++}
++
++/**
++ * Configure the end points for DYNAMIC FIFO: array based End point
++ * configuration.
++ * @param pThis the controller
+ */
++void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
++ uint8_t bEnd, bSkip;
++ MGC_LinuxLocalEnd* pEnd;
++ uint16_t wFifoOffset=0;
++
++ /* use the defined end points */
++ pThis->bEndCount=MUSB_C_NUM_EPS;
++
++#ifdef MUSB_PARANOID
++ if ( MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_T_CNTRL
++ && MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_AUTOCONFIG)
++ {
++ WARN("ep0 must be control with fixed size of %d\n",
++ MGC_END0_FIFOSIZE);
++ }
++#endif
++
++ /* entry 0 is ep0, the default control endpoint */
++ for (bEnd=0; bEnd<MUSB_C_NUM_EPS; bEnd++) {
++ bSkip=0;
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
++ pEnd->bIsSharedFifo = FALSE;
++ pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=0;
++
++ switch ( MUSB_aEpFifoDescriptors[bEnd].bType ) {
++ case MUSB_EPD_T_CNTRL:
++ if ( bEnd ) {
++ bSkip=1;
++ WARN("Control ep when ep!=0 (ep%d); skipping\n", bEnd);
++ }
++ break;
++
++ case MUSB_EPD_T_ISOC: break;
++
++ case MUSB_EPD_T_BULK:
++ switch ( MUSB_aEpFifoDescriptors[bEnd].bDir ) {
++ case MUSB_EPD_D_TX: pThis->bBulkTxEnd = bEnd; break;
++ case MUSB_EPD_D_RX: pThis->bBulkRxEnd = bEnd; break;
++ case MUSB_EPD_D_INOUT:
++ WARN("INOUTBULK: sharing ep%d\n", bEnd);
++ break;
++ default:
++ bSkip=1;
++ ERR("direction %d not supported for ep%d\n",
++ MUSB_aEpFifoDescriptors[bEnd].bDir, bEnd);
++ break;
++ }
++ break;
+
-+#define MUSB_MONITOR_DATA
++ case MUSB_EPD_T_INTR: break;
++ case MUSB_EPD_AUTOCONFIG: break;
+
-+#define yprintk(facility, format, args...) do { printk(facility "%s %d: " format , \
-+ __FUNCTION__, __LINE__ , ## args); } while (0)
-+#define WARN(fmt, args...) yprintk(KERN_WARNING,fmt, ## args)
-+#define INFO(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
-+#define ERR(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
++ default:
++ bSkip=1;
++ ERR("ep%d type %d not supported\n", bEnd,
++ MUSB_aEpFifoDescriptors[bEnd].bType);
++ break;
++ }
+
-+#if MUSB_DEBUG > 0
++ if ( !MUSB_aEpFifoDescriptors[bEnd].wSize ) {
++ continue; /* postpone to autoconfig */
++ }
+
-+#define STATIC
-+#define MGC_GetDebugLevel() (MGC_DebugLevel)
-+#define MGC_EnableDebug() do { MGC_DebugDisable=0; } while(0)
-+#define MGC_DisableDebug() do { MGC_DebugDisable=1; } while(0)
++ if ( !bSkip ) {
++ uint16_t offset=CONFIGURE_FIFO(pThis, &(pThis->aLocalEnd[bEnd]),
++ &MUSB_aEpFifoDescriptors[bEnd], wFifoOffset );
++ if ( offset ) {
++ wFifoOffset += offset;
++ }
++ }
+
-+#define _dbg_level(level) ( !MGC_DebugDisable && ((level>=-1 && MGC_GetDebugLevel()>=level) || MGC_GetDebugLevel()==level) )
++ }
+
-+#define xprintk(level, facility, format, args...) do { if ( _dbg_level(level) ) { \
-+ printk(facility "%s %d: " format , __FUNCTION__, __LINE__ , ## args); } } while (0)
-+
-+#define PARANOID( x ) do {} while (0)
-+#define DBG(level,fmt,args...) xprintk(level,KERN_INFO,fmt, ## args)
-+#define DEBUG_CODE(level, code) do { if ( _dbg_level(level) ) { code } } while (0)
-+#define TRACE(n) DEBUG_CODE(n, printk(KERN_INFO "%s:%s:%d: trace\n", \
-+ __FILE__, __FUNCTION__, __LINE__); )
++#ifdef MUSB_PARANOID
++ if ( wFifoOffset > 64 ) {
++ ERR("Allocated %d bytes, more than the allowed %d\n",
++ wFifoOffset, 64);
++ } else {
++ INFO("Allocated %d bytes, out of %d\n", wFifoOffset,
++ 64);
++ }
++#endif
+
-+#define ASSERT_SPINLOCK_LOCKED(_x)
-+#define ASSERT_SPINLOCK_UNLOCKED(_x)
-+/* #define ASSERT_SPINLOCK_LOCKED(_x) do { if (!spin_is_locked(_x)) \
-+ ERR("@pre clause failed, _x must be locked\n"); } while (0)
-+#define ASSERT_SPINLOCK_UNLOCKED(_x) do { if (spin_is_locked(_x)) \
-+ ERR("@pre clause failed, _x must be unlocked\n"); } while (0) */
++}
+
-+/* debug no defined */
++#else
++/**
++ * Configure the end points for DYNAMIC FIFO (old method).
++ * @param pThis the controller
++ */
++void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
++ uint8_t bEnd=1;
++ MGC_LinuxLocalEnd* pEnd;
++ void* pBase = pThis->pRegs;
++ uint16_t wFifoOffset=MGC_END0_FIFOSIZE;
+
-+#else
++ DBG(2, "<==\n");
+
-+#define STATIC static
-+#define MGC_GetDebugLevel() 0
-+#define MGC_EnableDebug()
-+#define MGC_DisableDebug()
++ /* use the defined end points */
++ pThis->bEndCount=MUSB_C_NUM_EPS;
+
-+#define PARANOID( x ) do {} while (0)
-+#define DBG(fmt,args...) do {} while (0)
-+#define DEBUG_CODE(x, y) do {} while (0)
-+#define TRACE(n) do {} while (0)
++ /* Dynamic FIFO sizing: use pre-computed values for EP0 */
++ MGC_SelectEnd(pBase, 0);
++ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 3);
++ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 3);
++ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 0);
++ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, 0);
++ pThis->wEndMask = 1;
+
-+#define ASSERT_SPINLOCK_LOCKED(_x)
-+#define ASSERT_SPINLOCK_UNLOCKED(_x)
++#if MGC_DFIFO_ISO_TX >= 0
++ MGC_SelectEnd(pBase, bEnd);
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
+
++ /* reserve ISO Tx */
++ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ISO_TX_VAL);
++ pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_ISO_TX_VAL & 0xf)+3+(MGC_DFIFO_ISO_TX_VAL>>4));
++ pEnd->wMaxPacketSizeRx = 0;
++ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
++ /* move to next */
++ wFifoOffset += pEnd->wMaxPacketSizeTx;
++ pEnd->bIsSharedFifo = FALSE;
++ pThis->wEndMask |= (1 << bEnd);
++ bEnd++;
+#endif
+
-+/*----------------------- DEBUG function/macros -----------------------------*/
-+
-+#if MUSB_DEBUG > 0
-+struct usb_ep;
-+struct list_head;
-+struct usb_request;
-+struct usb_ctrlrequest;
++#if MGC_DFIFO_ISO_RX >= 0
++ MGC_SelectEnd(pBase, bEnd);
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
+
-+extern int MGC_DebugLevel;
-+extern int MGC_DebugDisable;
++ /* reserve ISO Rx */
++ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ISO_RX_VAL);
++ pEnd->wMaxPacketSizeTx = 0;
++ pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_ISO_RX_VAL & 0xf)+3+(MGC_DFIFO_ISO_RX_VAL>>4));
++ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
+
-+extern void dump_urb(void *urb);
-+extern char *decode_csr0(uint16_t csr0);
-+extern char *decode_txcsr(uint16_t txcsr);
-+extern char *decode_devctl(uint16_t devclt);
-+extern char *decode_ep0stage(uint8_t stage);
-+extern char *dump_node(struct list_head *node);
-+extern char *decode_usb_ctrlrequest(const struct usb_ctrlrequest *pControlRequest);
-+extern char *decode_request(struct usb_ctrlrequest*) ;
-+extern void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd);
++ /* move to next */
++ wFifoOffset += pEnd->wMaxPacketSizeRx;
++ pEnd->bIsSharedFifo = FALSE;
++ pThis->wEndMask |= (1 << bEnd);
++ bEnd++;
+#endif
+
-+#endif // __MUSB_LINUX_DEBUG_H__
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/dma.h ../new/linux-2.6.20/drivers/usb/nomadik/dma.h
---- linux-2.6.20/drivers/usb/nomadik/dma.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/dma.h 2008-07-28 15:20:50.000000000 +0530
-@@ -0,0 +1,308 @@
-+/*
-+ * linux/drivers/usb/nomadik/dma.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
++ MGC_SelectEnd(pBase, bEnd);
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
+
-+#ifndef __MUSB_DMA_H__
-+#define __MUSB_DMA_H__
++ /* reserve bulk */
++ pEnd->wMaxPacketSizeRx= 0;
++ pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
++ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_BLK_VAL);
++ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
++ pThis->bBulkTxEnd = bEnd;
++ /* move to next */
++ wFifoOffset += pEnd->wMaxPacketSizeTx;
++ pThis->wEndMask |= (1 << bEnd);
++ bEnd++;
+
-+/**
-+ * Introduction.
-+ * The purpose of the DMA Controller Abstraction (DCA) is to allow the ICD
-+ * to use any DMA controller,
-+ * since this is an option in the Inventra USB cores.
-+ * The assumptions are:
-+ * <ul>
-+ * <li>A DMA controller will be tied to an Inventra USB core in the
-+ * way specified in the Inventra core product specification.
-+ * <li>A DMA controller's base address in the memory map correlates
-+ * somehow to the Inventra USB core it serves.
-+ * </ul>
-+ * The responsibilities of an implementation include:
-+ * <ul>
-+ * <li>Allocating/releasing buffers for use with DMA
-+ * (this may be specific to a DMA controller, intervening busses,
-+ * and a target's capabilities,
-+ * so the ICD cannot make assumptions or provide services here)
-+ * <li>Handling the details of moving multiple USB packets
-+ * in cooperation with the Inventra USB core.
-+ * <li>Knowing the correlation between channels and the
-+ * Inventra core's local endpoint resources and data direction,
-+ * and maintaining a list of allocated/available channels.
-+ * <li>Updating channel status on interrupts,
-+ * whether shared with the Inventra core or separate.
-+ * <li>If the DMA interrupt is shared with the Inventra core,
-+ * handling it when called, and reporting whether it was the
-+ * source of interrupt.
-+ * </ul>
-+ */
++ MGC_SelectEnd(pBase, bEnd);
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
+
-+/*************************** CONSTANTS ****************************/
++ pEnd->wMaxPacketSizeTx= 0;
++ pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
++ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_BLK_VAL);
++ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
++ pThis->bBulkRxEnd = bEnd;
++ /* move to next */
++ wFifoOffset += pEnd->wMaxPacketSizeRx;
++ pThis->wEndMask |= (1 << bEnd);
++ bEnd++;
+
-+/**
-+ * DMA channel status.
-+ */
-+typedef enum
-+{
-+ /** A channel's status is unknown */
-+ MGC_DMA_STATUS_UNKNOWN,
-+ /** A channel is available (not busy and no errors) */
-+ MGC_DMA_STATUS_FREE,
-+ /** A channel is busy (not finished attempting its transactions) */
-+ MGC_DMA_STATUS_BUSY,
-+ /** A channel aborted its transactions due to a local bus error */
-+ MGC_DMA_STATUS_BUS_ABORT,
-+ /** A channel aborted its transactions due to a core error */
-+ MGC_DMA_STATUS_CORE_ABORT
-+} MGC_DmaChannelStatus;
++ /* take care of the remaining eps */
++ for(; bEnd < MUSB_C_NUM_EPS; bEnd++) {
++ MGC_SelectEnd(pBase, bEnd);
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
+
-+/***************************** TYPES ******************************/
++ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ALL_VAL);
++ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ALL_VAL);
++ pEnd->wMaxPacketSizeTx = pEnd->wMaxPacketSizeRx = 1 << (MGC_DFIFO_ALL_VAL+3);
++ pEnd->bIsSharedFifo = TRUE;
++ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
++ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
+
-+/**
-+ * MGC_DmaChannel.
-+ * A DMA channel.
-+ * @field pPrivateData channel-private data; not to be interpreted by the ICD
-+ * @field wMaxLength the maximum number of bytes the channel can move
-+ * in one transaction (typically representing many USB maximum-sized packets)
-+ * @field dwActualLength how many bytes have been transferred
-+ * @field bStatus current channel status (updated e.g. on interrupt)
-+ * @field bDesiredMode TRUE if mode 1 is desired; FALSE if mode 0 is desired
-+ */
-+typedef struct
-+{
-+ void* pPrivateData;
-+ uint32_t dwMaxLength;
-+ uint32_t dwActualLength;
-+ MGC_DmaChannelStatus bStatus;
-+ uint8_t bDesiredMode;
-+} MGC_DmaChannel;
++ wFifoOffset += pEnd->wMaxPacketSizeRx;
++ pThis->wEndMask |= (1 << bEnd);
++ }
+
-+/**
-+ * Start a DMA controller.
-+ * @param pPrivateData private data pointer from MGC_DmaController
-+ * @return TRUE on success
-+ * @return FALSE on failure (e.g. no DMAC appears present)
-+ */
-+typedef uint8_t (*MGC_pfDmaStartController)(void* pPrivateData);
++#ifdef MUSB_PARANOID
++ if ( wFifoOffset > 64 ) {
++ ERR("Allocated %d bytes, more than the allowed %d\n",
++ wFifoOffset, 64);
++ } else {
++ INFO("Allocated %d bytes, out of %d\n",
++ wFifoOffset, 64);
++ }
++#endif
+
-+/**
-+ * Stop a DMA controller.
-+ * @param pPrivateData the controller's private data pointer
-+ * @return TRUE on success
-+ * @return FALSE on failure; the ICD may try again
-+ */
-+typedef uint8_t (*MGC_pfDmaStopController)(void* pPrivateData);
++ DBG(2, "==>\n");
++}
++#endif
+
++#else
+/**
-+ * Allocate a DMA channel.
-+ * Allocate a DMA channel suitable for the given conditions.
-+ * @param pPrivateData the controller's private data pointer
-+ * @param bLocalEnd the local endpoint index (1-15)
-+ * @param bTransmit TRUE for transmit; FALSE for receive
-+ * @param bProtocol the USB protocol, as per USB 2.0 chapter 9
-+ * (0 => control, 1 => isochronous, 2 => bulk, 3 => interrupt)
-+ * @param wMaxPacketSize maximum packet size
-+ * @return a non-NULL pointer on success
-+ * @return NULL on failure (no channel available)
++ * Detect and configure the end points (no dynamic fifos).
++ * @param pThis the controller
+ */
-+typedef MGC_DmaChannel* (*MGC_pfDmaAllocateChannel)(
-+ void* pPrivateData, uint8_t bLocalEnd,
-+ uint8_t bTransmit, uint8_t bProtocol, uint16_t wMaxPacketSize);
++void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
++ uint8_t bEnd=0, reg;
++ MGC_LinuxLocalEnd* pEnd;
++ void* pBase = pThis->pRegs;
++ /* how many of a given size/direction found: */
++ uint8_t b2kTxEndCount = 0;
++ uint8_t b2kRxEndCount = 0;
++ uint8_t b1kTxEndCount = 0;
++ uint8_t b1kRxEndCount = 0;
++ /* the smallest 2k or 1k ends in Tx or Rx direction: */
++ uint8_t b2kTxEnd = 0;
++ uint8_t b2kRxEnd = 0;
++ uint8_t b1kTxEnd = 0;
++ uint8_t b1kRxEnd = 0;
++ /* for tracking smallest: */
++ uint16_t w2kTxSize = 0;
++ uint16_t w1kTxSize = 0;
++ uint16_t w2kRxSize = 0;
++ uint16_t w1kRxSize = 0;
+
-+/**
-+ * Release a DMA channel.
-+ * Release a previously-allocated DMA channel.
-+ * The ICD guarantess to no longer reference this channel.
-+ * @param pChannel pointer to a channel obtained by
-+ * a successful call to pController->pfDmaAllocateChannel
-+ */
-+typedef void (*MGC_pfDmaReleaseChannel)(MGC_DmaChannel* pChannel);
++ DBG(2, ">==\n");
+
-+/**
-+ * Allocate DMA buffer.
-+ * Allocate a buffer suitable for DMA operations with the given channel.
-+ * @param pChannel pointer to a channel obtained by
-+ * a successful call to pController->pfDmaAllocateChannel
-+ * @param dwLength length, in bytes, desired for the buffer
-+ * @return a non-NULL pointer to a suitable region (in processor space)
-+ * on success
-+ * @return NULL on failure
-+ */
-+typedef uint8_t* (*MGC_pfDmaAllocateBuffer)(MGC_DmaChannel* pChannel,
-+ uint32_t dwLength);
++ for(bEnd = 1; bEnd < MUSB_C_NUM_EPS; bEnd++) {
++ MGC_SelectEnd(pBase, bEnd);
++ pEnd = &(pThis->aLocalEnd[bEnd]);
++ pEnd->bEnd=bEnd;
+
-+/**
-+ * Release DMA buffer.
-+ * Release a DMA buffer previously acquiring by a successful call
-+ * to pController->pfDmaAllocateBuffer.
-+ * @param pChannel pointer to a channel obtained by
-+ * a successful call to pController->pfDmaAllocateChannel
-+ * @param pBuffer the buffer pointer
-+ * @return TRUE on success
-+ * @return FALSE on failure (e.g. the controller owns the buffer at present)
-+ */
-+typedef uint8_t (*MGC_pfDmaReleaseBuffer)(MGC_DmaChannel* pChannel,
-+ uint8_t* pBuffer);
++ /* read from core */
++ reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_FIFOSIZE, bEnd);
++ if(!reg) {
++ /* 0's returned when no more endpoints */
++ break;
++ }
+
-+/**
-+ * Program a DMA channel.
-+ * Program a DMA channel to move data at the core's request.
-+ * The local core endpoint and direction should already be known,
-+ * since they are specified in the pfDmaAllocateChannel call.
-+ * @param pChannel pointer to a channel obtained by
-+ * a successful call to pController->pfDmaAllocateChannel
-+ * @param wPacketSize the packet size
-+ * @param bMode TRUE if mode 1; FALSE if mode 0
-+ * @param pBuffer base address of data (in processor space)
-+ * @param dwLength the number of bytes to transfer;
-+ * guaranteed by the ICD to be no larger than the channel's reported dwMaxLength
-+ * @return TRUE on success
-+ * @return FALSE on error
-+ */
-+typedef uint8_t (*MGC_pfDmaProgramChannel)(MGC_DmaChannel* pChannel,
-+ uint16_t wPacketSize, uint8_t bMode,
-+ const uint8_t* pBuffer,
-+ uint32_t dwLength);
++ pEnd->wMaxPacketSizeTx = 1 << (reg & 0x0f);
++ /* shared TX/RX FIFO? */
++ if((reg & 0xf0) == 0xf0) {
++ pEnd->wMaxPacketSizeRx = 1 << (reg & 0x0f);
++ pEnd->bIsSharedFifo = TRUE;
++ } else {
++ pEnd->wMaxPacketSizeRx = 1 << ((reg & 0xf0) >> 4);
++ pEnd->bIsSharedFifo = FALSE;
++ }
+
-+/**
-+ * Get DMA channel status.
-+ * Get the current status of a DMA channel, if the hardware allows.
-+ * @param pChannel pointer to a channel obtained by
-+ * a successful call to pController->DmaAllocateChannel
-+ * @return current status
-+ * (MGC_DMA_STATUS_UNKNOWN if hardware does not have readable status)
-+ */
-+typedef MGC_DmaChannelStatus (*MGC_pfDmaGetChannelStatus)(
-+ MGC_DmaChannel* pChannel);
++ /* track certain sizes to try to reserve a bulk resource */
++ if(pEnd->wMaxPacketSizeTx >= 2048) {
++ b2kTxEndCount++;
++ if(!b2kTxEnd || (pEnd->wMaxPacketSizeTx < w2kTxSize)) {
++ b2kTxEnd = bEnd;
++ w2kTxSize = pEnd->wMaxPacketSizeTx;
++ }
++ }
+
-+/**
-+ * DMA ISR.
-+ * If present, this function is called by the ICD on every interrupt.
-+ * This is necessary because with the built-in DMA controller
-+ * (and probably some other configurations),
-+ * the DMA interrupt is shared with other core interrupts.
-+ * Therefore, this function should return quickly
-+ * when there is no DMA interrupt.
-+ * When there is a DMA interrupt, this function should
-+ * perform any implementations-specific operations,
-+ * and update the status of all appropriate channels.
-+ * If the DMA controller has its own dedicated interrupt,
-+ * this function should do nothing.
-+ * This function is called BEFORE the ICD handles other interrupts.
-+ * @param pPrivateData the controller's private data pointer
-+ * @return TRUE if an interrupt was serviced
-+ * @return FALSE if no interrupt required servicing
-+ */
-+typedef uint8_t (*MGC_pfDmaControllerIsr)(void* pPrivateData);
++ if(pEnd->wMaxPacketSizeRx >= 2048) {
++ b2kRxEndCount++;
++ if(!b2kRxEnd || (pEnd->wMaxPacketSizeRx < w2kRxSize)) {
++ b2kRxEnd = bEnd;
++ w2kRxSize = pEnd->wMaxPacketSizeRx;
++ }
++ }
+
-+/**
-+ * MGC_DmaController.
-+ * A DMA Controller.
-+ * This is in a struct to allow the ICD to support
-+ * multiple cores of different types,
-+ * since each may use a different type of DMA controller.
-+ * @field pPrivateData controller-private data;
-+ * not to be interpreted by the ICD
-+ * @field pfDmaStartController ICD calls this to start a DMA controller
-+ * @field pfDmaStopController ICD calls this to stop a DMA controller
-+ * @field pfDmaAllocateChannel ICD calls this to allocate a DMA channel
-+ * @field pfDmaReleaseChannel ICD calls this to release a DMA channel
-+ * @field pfDmaAllocateBuffer ICD calls this to allocate a DMA buffer
-+ * @field pfDmaReleaseBuffer ICD calls this to release a DMA buffer
-+ * @field pfDmaGetChannelStatus ICD calls this to get a DMA channel's status
-+ * @field pfDmaControllerIsr ICD calls this (if non-NULL) from its ISR
-+ */
-+typedef struct
-+{
-+ void* pPrivateData;
-+ MGC_pfDmaStartController pfDmaStartController;
-+ MGC_pfDmaStopController pfDmaStopController;
-+ MGC_pfDmaAllocateChannel pfDmaAllocateChannel;
-+ MGC_pfDmaReleaseChannel pfDmaReleaseChannel;
-+ MGC_pfDmaAllocateBuffer pfDmaAllocateBuffer;
-+ MGC_pfDmaReleaseBuffer pfDmaReleaseBuffer;
-+ MGC_pfDmaProgramChannel pfDmaProgramChannel;
-+ MGC_pfDmaGetChannelStatus pfDmaGetChannelStatus;
-+ MGC_pfDmaControllerIsr pfDmaControllerIsr;
-+} MGC_DmaController;
++ if(pEnd->wMaxPacketSizeTx >= 1024) {
++ b1kTxEndCount++;
++ if(!b1kTxEnd || (pEnd->wMaxPacketSizeTx < w1kTxSize)) {
++ b1kTxEnd = bEnd;
++ w1kTxSize = pEnd->wMaxPacketSizeTx;
++ }
++ }
+
-+/**
-+ * A DMA channel has new status.
-+ * This may be used to notify the ICD of channel status changes asynchronously.
-+ * This is useful if the DMA interrupt is different from the USB controller's
-+ * interrupt, so on some systems there may be no control over the order of
-+ * USB controller and DMA controller assertion.
-+ * @param pPrivateData the controller's private data pointer
-+ * @param bLocalEnd the local endpoint index (1-15)
-+ * @param bTransmit TRUE for transmit; FALSE for receive
-+ * @return TRUE if an IRP was completed as a result of this call;
-+ * FALSE otherwise
-+ */
-+typedef uint8_t (*MGC_pfDmaChannelStatusChanged)(
-+ void* pPrivateData, uint8_t bLocalEnd,
-+ uint8_t bTransmit);
++ if(pEnd->wMaxPacketSizeRx >= 1024) {
++ b1kRxEndCount++;
++ if(!b1kRxEnd || (pEnd->wMaxPacketSizeRx < w1kTxSize)) {
++ b1kRxEnd = bEnd;
++ w1kRxSize = pEnd->wMaxPacketSizeRx;
++ }
++ }
+
-+/**
-+ * Instantiate a DMA controller.
-+ * Instantiate a software object representing a DMA controller.
-+ * @param pfDmaChannelStatusChanged channel status change notification function.
-+ * Normally, the ICD requests status in its interrupt handler.
-+ * For some DMA controllers, this may not be the correct time.
-+ * @param pDmaPrivate parameter for pfDmaChannelStatusChanged
-+ * @param pCoreBase the base address (in kernel space) of the core
-+ * It is assumed the DMA controller's registers' base address will be related
-+ * to this in some way.
-+ * @return non-NULL pointer on success
-+ * @return NULL on failure (out of memory or exhausted
-+ * a fixed number of controllers)
-+ */
-+typedef MGC_DmaController* (*MGC_pfNewDmaController)(
-+ MGC_pfDmaChannelStatusChanged pfDmaChannelStatusChanged,
-+ void* pDmaPrivate,
-+ uint8_t* pCoreBase);
++ pThis->bEndCount++;
++ pThis->wEndMask |= (1 << bEnd);
++ } /* init queues etc. etc. etc. */
+
-+/**
-+ * Destroy DMA controller.
-+ * Destroy a previously-instantiated DMA controller.
-+ */
-+typedef void (*MGC_pfDestroyDmaController)(
-+ MGC_DmaController* pController);
++ /* if possible, reserve the smallest 2k-capable Tx end for bulk */
++ if(b2kTxEnd && (b2kTxEndCount > 1)) {
++ pThis->bBulkTxEnd = b2kTxEnd;
++ INFO("Reserved end %d for bulk double-buffered Tx\n", b2kTxEnd);
++ }
++ /* ...or try 1k */
++ else if(b1kTxEnd && (b1kTxEndCount > 1)) {
++ pThis->bBulkTxEnd = b1kTxEnd;
++ INFO("Reserved end %d for bulk Tx\n", b1kTxEnd);
++ }
+
-+/**
-+ * MGC_DmaControllerFactory.
-+ * A DMA controller factory.
-+ * To allow for multi-core implementations and different
-+ * types of cores and DMA controllers to co-exist,
-+ * it is necessary to create them from factories.
-+ * @field wCoreRegistersExtent the total size of the core's
-+ * register region with the DMA controller present,
-+ * for use in mapping the core into system memory.
-+ * For example, the MHDRC core takes 0x200 bytes of address space.
-+ * If your DMA controller starts at 0x200 and takes 0x100 bytes,
-+ * set this to 0x300.
-+ * @field pfNewDmaController create a DMA controller
-+ * @field pfDestroyDmaController destroy a DMA controller
-+ */
-+typedef struct
-+{
-+ uint16_t wCoreRegistersExtent;
-+ MGC_pfNewDmaController pfNewDmaController;
-+ MGC_pfDestroyDmaController pfDestroyDmaController;
-+} MGC_DmaControllerFactory;
++ /* if possible, reserve the smallest 2k-capable Rx end for bulk */
++ if(b2kRxEnd && (b2kRxEndCount > 1)) {
++ pThis->bBulkRxEnd = b2kRxEnd;
++ INFO("Reserved end %d for bulk double-buffered Rx\n", b2kRxEnd);
++ }
++ /* ...or try 1k */
++ else if(b1kRxEnd && (b1kRxEndCount > 1)) {
++ pThis->bBulkRxEnd = b1kRxEnd;
++ INFO("Reserved end %d for bulk Rx\n", b1kRxEnd);
++ }
+
-+#endif /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/g_ep0.c ../new/linux-2.6.20/drivers/usb/nomadik/g_ep0.c
---- linux-2.6.20/drivers/usb/nomadik/g_ep0.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/g_ep0.c 2008-08-08 19:15:20.000000000 +0530
-@@ -0,0 +1,858 @@
++ DBG(2, "<==\n");
++}
++#endif
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_hcd.c
+@@ -0,0 +1,869 @@
+/*
-+ * linux/drivers/usb/nomadik/g_ep0.c
++ * linux/drivers/usb/nomadik/musb_hcd.c
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/timer.h>
-+#include <linux/spinlock.h>
-+
-+#if defined(MUSB_V24) && !defined(MUSB_LINUX_MV21)
-+/* dealing with Linux headers */
-+struct usb_tt {
-+ struct usb_device *hub; /* upstream highspeed hub */
-+ int multi; /* true means one TT per port */
-+};
-+#include "hcd.h"
-+#endif
-+
-+#include <linux/init.h>
-+#include <linux/usb_ch9.h>
-+#include "musbdefs.h"
-+#include "musb_gadgetdefs.h"
++#include <asm/arch/pexp.h>
++static void mgc_hcd_stop(struct usb_hcd *hcd);
++static int __devinit mgc_hcd_start(struct usb_hcd *hcd);
++static int mgc_hcd_submit_urb(struct usb_hcd *hcd,struct usb_host_endpoint *ep,
++ struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
++static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb);
++static int mgc_hcd_get_frame_number(struct usb_hcd *hcd);
++static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd);
++static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd,
++ struct usb_host_endpoint *ep);
++static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
+
++static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, char *pData, u16 wLength);
++static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData);
++int Urb_status=0;
++/* ------------------------------------------------------- */
++static int mgc_bus_resume(struct usb_hcd *phcd)
++{
++ MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
++ char* pBase = (char*)pThis->pRegs;
+
-+/* ---------------------------------------------------------------------- */
++ nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
++ /* Reinitialize the interrupt*/
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, 0x20);
++ MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0xFFFF);
++ MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0xFFFE);
++ MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xF7);
++ MGC_Write8(pBase, MGC_O_HDRC_INDEX ,0x00);
+
-+/**
-+ * Identifies a transmit request.
-+ * @param pControlRequest the control request
-+ * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE,
-+ * USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME
-+ */
-+uint8_t is_tx_request(const struct usb_ctrlrequest *pControlRequest)
-+{
-+ return ( pControlRequest->bRequestType & USB_DIR_IN );
-+}
++ /* Configure the endpoints*/
++ MGC_HdrcConfigureEps(pThis);
++ MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);
++ mod_timer(¬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<num> to control the
++ if ( !MUSB_IS_HST(pThis) ) {
++ break; /* nothing to do */
++ }
+
-+ NOTE: this is different from supporting /proc filesystem;
++ spin_lock(&pQueue->urb_queue_lock);
++ pUrb=mgc_hcd_urb_pop(pQueue);
++ if ( !pUrb ) {
++ DBG(3, "scheduler is idle\n");
++ spin_unlock(&pQueue->urb_queue_lock);
++ break;
++ }
+
-+ If you do not know what this is, please say N.
++ DBG(3, "pUrb=%p, (proto=%s)\n", pUrb, decode_urb_protocol(pUrb));
++ nEnd=mgc_hcd_find_end(pThis, pUrb);
++ if ( nEnd<0 ) {
++ spin_unlock(&pQueue->urb_queue_lock);
++ ERR("***> no resource for proto=%s, addr=%d, end=%d\n",
++ decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe),
++ usb_pipeendpoint(pUrb->pipe));
++ if ( !pQueue->urb_exec_count ) {
++ /* push it back and give it another chance */
++ mgc_hcd_urb_pushback(pQueue, pUrb);
++ ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n",
++ pUrb, nEnd, rc);
++ break;
++ } else {
++ /* the urb will never be scheduled, kill it and move to next */
++ usb_kill_urb(pUrb);
++ ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n",
++ pUrb, nEnd);
++ continue;
++ }
++ }
+
-+config USB_INVENTRA_HCD_CUSTOM_OPTIONS
-+ depends on USB_INVENTRA_HCD
-+ string 'Custom compile options (Advanced)'
-+ default ''
-+ help
-+ Specify a custom compile options (Advanced)
-+
-+config USB_INVENTRA_HCD_POLLING
-+ depends on USB_INVENTRA_HCD
-+ bool 'Use polling driver (debug only)'
-+ default false
-+ help
-+ Enable polling mode (events won't be triggered by IRQs); usefule
-+ for debugging.
++ pEnd=&pThis->aLocalEnd[nEnd];
++ if ( mgc_ep_is_idle(pEnd) ) {
++ DBG(3, "(%d/%d) pUrb=%p, nEnd=%d, %s \n",
++ pQueue->urb_queue_count, pQueue->urb_exec_count,
++ pUrb, nEnd, mgc_ep_is_idle(pEnd)?"idle":"busy");
++ spin_unlock(&pQueue->urb_queue_lock);
++ rc=mgc_schedule_urb(pThis, pEnd, pUrb);
++ if ( rc!=0 ) {
++ if ( !pQueue->urb_exec_count ) {
++ /* the urb will never be scheduled, kill it */
++ usb_kill_urb(pUrb);
++ ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n",
++ pUrb, nEnd);
++ } else {
++ /* push it back and give it another chance */
++ mgc_hcd_urb_pushback(pQueue, pUrb);
++ ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n",
++ pUrb, nEnd, rc);
++ }
++ } else {
++ /* removed from the queue, scheduled to hardware */
++ pQueue->urb_exec_count++;
++ break;
++ }
++ } else { /* too fast ? */
++ mgc_hcd_urb_pushback(pQueue, pUrb);
++ spin_unlock(&pQueue->urb_queue_lock);
++ DBG(3, "???> cannot schedule pUrb=%p to nEnd=%d yet (busy with pEnd->pCurrentUrb=%p)\n",
++ pUrb, nEnd, MGC_GetCurrentUrb(pEnd));
++ break;
++ }
+
-+ If you do not know what this is, please say N.
++ } while ( 1 );
+
-+config USB_INVENTRA_HCD_LOGGING
-+ depends on USB_INVENTRA_HCD
-+ int 'Logging Level (0 - none / 3 - annoying)'
-+ default 0
-+ help
-+ Set the logging level. 0 disable the debugging altogether (no
-+ code will be added to the)
-+
-+ If you do not know what this is, please say N.
++ DBG(2, "==> rc=%d\n", rc);
++ return rc;
++}
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/logx ../new/linux-2.6.20/drivers/usb/nomadik/logx
---- linux-2.6.20/drivers/usb/nomadik/logx 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/logx 2008-07-04 23:45:36.000000000 +0530
-@@ -0,0 +1 @@
-+make: *** No rule to make target `vmlinux'. Stop.
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/Makefile ../new/linux-2.6.20/drivers/usb/nomadik/Makefile
---- linux-2.6.20/drivers/usb/nomadik/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/Makefile 2008-07-04 23:45:36.000000000 +0530
-@@ -0,0 +1,97 @@
-+MUSB_VERSION=2.2.2
-+HCD_TYPE=hcd
++/* ------------------------------------------------------------------ */
+
++/**
++ * Find a local endpoint suitable for transmitting the given urb minimizing
++ * the reconfigurations. The best localendpoint is selceted using the following
++ * criterion:
++ * - ep0 is used for control Urbs
++ * - for bulk Urbs only (when available) choose the Tx or Rx reserved end
++ * - determine direction, size and traffic type
++ *
++ * @param pThis instance pointer
++ * @param pURB URB pointer
++ * @return suitable local endpoint
++ * @return -1 if nothing appropriate
++ */
++static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb)
++{
++ return mgc_linux_find_end(pThis, pUrb);
++}
+
-+obj-$(CONFIG_USB_INVENTRA_HCD) += musb-hcd.o
++/**
++ * Submit an urb to our HCD driver. The urb will be queued and (sooner or later)
++ * scheduled to the hardware driver. The Urb had been queued to the ep from the
++ * kernel, DON'T modify with the urb_list otherwise BAD THINGS WILL
++ * HAPPEN (TM).
++ * @param hcd the HCD driver
++ * @param pURB URB pointer
++ */
++static int mgc_hcd_submit_urb(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
++ struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags)
++{
+
++ int rc=0;
+
++ MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
+
-+ifeq ($(CONFIG_PROC_FS),y)
-+ musb-$(HCD_TYPE)-objs += musb_procfs.o
-+endif
++ if(Urb_status==1)
++ {
++ pUrb->status=-ENODEV;
++ rc=-ENODEV;
++ return rc;
++ }
+
++#ifdef MUSB_PARANOID
++ if ( !pThis ) {
++ ERR("***==> pThis is null\n");
++ return -ENODEV;
++ }
+
-+ifneq ($(CONFIG_USB_INVENTRA_MUSB_BOARD_FILE),"")
-+ EXTRA_CFLAGS += -DMUSB_BOARD_FILE
-+endif
-+
-+ifneq ($(CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE),"")
-+EXTRA_CFLAGS += -DMUSB_HDR_CCNF_FILE
-+endif
-+
-+ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
-+ifneq ($(CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE),"")
-+EXTRA_CFLAGS += -DMUSB_EPFIFOCONFIG_FILE
-+endif
-+endif
++ if ( !pUrb ) {
++ ERR("***==> pUrb is NULL\n");
++ return -ENODEV;
++ }
+
-+ifneq ($(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS),"")
-+EXTRA_CFLAGS += $(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS)
-+endif
++ pUrb->hcpriv=NULL; /* paranoid!! */
++ pUrb->status=-EINPROGRESS; /* paranoid!! */
++#endif
+
++ DBG(2, "<== submit pUrb=%p, pUrb->hcpriv=%p, (proto=%s), bRemoteAddress=%d, bRemoteEnd=%d\n",
++ pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe),
++ usb_pipeendpoint(pUrb->pipe));
+
-+ EXTRA_CFLAGS += -DMUSB_C_DYNFIFO_DEF
-+ EXTRA_CFLAGS += -DMUSB_EPDISCRIPTORS_FILE
++ if ( pUrb->hcpriv ) {
++ ERR("***==> on submission pUrb->hcpriv=%p; this is BAD (TM)\n", pUrb->hcpriv);
++ return -ENODEV;
++ }
+
-+ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
-+ EXTRA_CFLAGS += -DMUSB_AHB_ID
-+endif
++ {
++ mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
++ int count=mgc_hcd_queue_urb(pQueue, pUrb);
++ if ( count<0 ) {
++ rc=-ENODEV;
++ } else if ( count==0 ) {
++ rc=mgc_hcd_schedule_urb(pThis);
++ /*printk("Queued for scheduled:%d\n",usb_pipeendpoint(pUrb->pipe));*/
++ } /* count>0 it's been queued */
++ /*else
++ {
++ printk("Count> 0:%d\n",usb_pipeendpoint(pUrb->pipe));
++ }*/
++ }
+
-+ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
-+ EXTRA_CFLAGS += -DMUSB_DMA
-+ musb-$(HCD_TYPE)-objs += musbhsdma.o
-+endif
+
-+EXTRA_CFLAGS += -DMUSB_VERSION='"$(MUSB_VERSION)"' -DHCD_NAME=$(HCD_NAME)
+
-+ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
-+ EXTRA_CFLAGS += -DMUSB_STATIC_CONFIG
-+endif
++ DBG(2, "==> rc=%d\n", rc);
++ return rc;
++}
+
-+ifeq ($(CONFIG_USB_INVENTRA_HCD_OTG),y)
-+ GADGET_API=y
-+ MUSB_HOSTMODE=y
-+ EXTRA_CFLAGS += -DMUSB_OTG
-+ musb-$(HCD_TYPE)-objs += otg.o
-+endif
++/**
++ * unlink an urb, hcd version. First check if the urb was queued to the
++ * hardware, if not search it in the hcd queue, if not... this is BAD
++ * (TM).
++ * @param hcd the HCD driver
++ * @param pURB URB pointer
++ */
++static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb)
++{
++ int rc=0;
++ MGC_LinuxLocalEnd* pEnd;
++ MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
++ mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
+
-+ifeq ($(CONFIG_USB_INVENTRA_HCD_GADGET_API),y)
-+ GADGET_API=y
-+endif
++#ifdef MUSB_PARANOID
++ if ( !pThis ) {
++ ERR("pThis is null");
++ return -ENODEV;
++ }
++#endif
+
-+#ifneq ($(GADGET_API),)
++ DBG(-1, "<== Unlinking pUrb=%p (%s), pUrb->hcpriv=%p\n", pUrb,
++ decode_urb_protocol(pUrb), pUrb->hcpriv);
++ spin_lock(&pQueue->urb_queue_lock);
++ pEnd=mgc_ep_find_end(pThis, pUrb);
++ if ( pEnd ) { /* was submitted */
++ spin_unlock(&pQueue->urb_queue_lock);
++ rc=mgc_unlink_urb(pThis, pUrb);
++ } else { /* remove the urb */
++ struct urb* prev;
++ prev=mgc_hcd_urb_find_prev(pQueue, pUrb);
++ if ( prev==NULL ) { /* not mine! */
++ ERR("*** cannot find pUrb=%p: is not mine! this is bad (tm)\n",
++ pUrb);
++ } else if ( prev==pUrb ) { /* list head */
++ pQueue->urb_queue_head=prev->hcpriv;
++ if ( pQueue->urb_queue_tail==prev ) {
++ pQueue->urb_queue_tail=prev->hcpriv;
++ }
++ } else {
++ prev->hcpriv=pUrb->hcpriv;
++ }
++ spin_unlock(&pQueue->urb_queue_lock);
++ }
+
-+# GADGET_DIRS=y
-+# EXTRA_CFLAGS += -DMUSB_GADGET
-+# musb-$(HCD_TYPE)-objs += musb_gadgetcommon.o g_ep0.o musb_gadget.o
-+#endif
++ DBG(2, "==> Unlinked urb=%p\n", pUrb);
++ return rc;
++}
+
++/**
++ * return the frame number
++ * @param hcd the HCD driver
++ * @return the frame number
++ */
++static int mgc_hcd_get_frame_number(struct usb_hcd *hcd) {
++ return mgc_get_frame_number( hcd_to_musbstruct(hcd) );
++}
+
-+ifeq ($(CONFIG_USB_INVENTRA_HCD_HOST),y)
-+ MUSB_HOSTMODE=y
-+endif
++/**
++ * Interrupt service routine, redirect it to the main routine/
++ * @param hcd the HCD driver
++ * @param r the pt registers
++ * @return
++ */
++static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd)
++{
++ return mgc_linux_isr( hcd_to_musbstruct(hcd) );
++}
+
++/**
++ * @param hcd the HCD driver
++ * @param ep the endpoint to disable
++ */
++static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd,
++ struct usb_host_endpoint *ep)
++{
++ DBG(-1, "hw sync with ep=%d (%s) list_empty(&ep->urb_list)=%d\n",
++ 0x7f&ep->desc.bEndpointAddress, (ep->desc.bEndpointAddress==0) ? "in/out"
++ : (ep->desc.bEndpointAddress>=0x80)?"in":"out",
++ list_empty(&ep->urb_list) );
+
-+ifeq ($(MUSB_HOSTMODE),y)
-+ EXTRA_CFLAGS += -DMUSB_HOST
-+ musb-$(HCD_TYPE)-objs += musb_virthub.o musb_host.o musb-hcd.o musb_plat_uds.o musb_bus_direct.o musb_epfifocfg.o musb_ioctl.o nomadik_udc.o otg_pwm.o otg_func.o
++ DBG(2, "<== disable endpoint %d (%s)\n", 0x7f&ep->desc.bEndpointAddress,
++ (ep->desc.bEndpointAddress==0) ? "in/out"
++ : (ep->desc.bEndpointAddress>=0x80)?"in":"out");
+
-+endif
++ DBG(2, "==>disabled endpoint %d\n", 0x7f&ep->desc.bEndpointAddress);
++}
+
-+ifndef DEBUG
-+ DEBUG=0
-+endif
++/* --------------------------------------------------------------- */
++/* Virtual hub */
++/* --------------------------------------------------------------- */
+
-+MUSB_DEBUG=$(CONFIG_USB_INVENTRA_HCD_LOGGING)
-+ifeq ("$(strip $(MUSB_DEBUG))","")
-+ MUSB_DEBUG:=$(DEBUG)
-+endif
++/**
++ * Report the virtual hub status.
++ *
++ * @param hcd the hcd
++ * @param pData the buffer to store the status in
++ */
++static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData)
++{
++ MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd);
++ MGC_VirtualHub* pHub = &(pThis->RootHub);
++ int len = 0;
+
++ spin_lock(&pHub->Lock);
++ len = mgc_rh_port_status(pHub, pData);
++ pHub->bIsChanged = FALSE;
++ spin_unlock(&pHub->Lock);
++ DBG(5, "len=%d, status=%02x\n", len, pData[0]);
++ return len;
++}
+
-+ifneq ($(MUSB_DEBUG),0)
-+ EXTRA_CFLAGS += -g
-+ musb-$(HCD_TYPE)-objs += musb_debug.o
-+endif
++/** MGC_VirtualhubControl Instead of MGC_VirtualHubSubmitUrb
++ * @param hcd the HCD driver
++ */
++static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, char *pData, u16 wLength)
++{
++ MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd);
++ MGC_VirtualHub* pHub = &(pThis->RootHub);
++ uint8_t bPort = (uint8_t)(wIndex & 0xff) - 1;
++ uint16_t wSize = 0xffff;
++ int retval = 0;
++ int ports = (pHub->bPortCount + 1);
+
-+EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
++ DBG("<==\n");
++ DBG("Setup_Data: bmReqtype-bmRequest=%04x | wValue=%x | wIndex=%x | wLength=%04x \n", \
++ typeReq, wValue, wIndex, wLength);
++ DBG("Setup_Data: wValue=%04x | wIndex=%04x | wLength=%04x | \n", \
++ wValue, wIndex, wLength);
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c
---- linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c 2008-08-08 19:15:21.000000000 +0530
-@@ -0,0 +1,371 @@
++ switch (typeReq) {
++ case ClearHubFeature:
++ switch (wValue) {
++ case C_HUB_LOCAL_POWER:
++ case C_HUB_OVER_CURRENT:
++ wSize = 0;
++ break;
++ default:
++ goto error;
++ }
++ break;
++ case ClearPortFeature:
++ if (!wIndex || wIndex > ports)
++ goto error;
++ wIndex--;
++ switch (wValue) {
++ case USB_PORT_FEAT_ENABLE:
++ DBG("enable port %d\n", bPort);
++ pHub->pPortServices->pfSetPortEnable(
++ pHub->pPortServices->pPrivateData, bPort, FALSE);
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_C_ENABLE:
++ DBG("ack enable port %d\n", bPort);
++ pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE;
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_SUSPEND:
++ DBG("suspend port %d\n", bPort);
++ pHub->pPortServices->pfSetPortSuspend(
++ pHub->pPortServices->pPrivateData, bPort, FALSE);
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_C_SUSPEND:
++ DBG("ack suspend port %d\n", bPort);
++ pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND;
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_POWER:
++ DBG("feat feat power port %d\n", bPort);
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_C_CONNECTION:
++ DBG("ack connection port %d\n", bPort);
++ pHub->aPortStatusChange[bPort].wChange &= ~1;
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_C_OVER_CURRENT:
++ DBG("ack over current port %d\n", bPort);
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_C_RESET:
++ DBG("ack reset port %d\n", bPort);
++ pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET;
++ wSize = 0;
++ break;
++ default:
++ goto error;
++ }
++ break;
++ case GetHubDescriptor:
++ DBG("GET_CLASS_DESCRIPTOR()\n");
++ pData[0] = 9;
++ pData[1] = 0x29;
++ pData[2] = pHub->bPortCount;
++ /* min characteristics */
++ pData[3] = 1; /* invidual port power switching */
++ pData[4] = 0;
++ /* PowerOn2PowerGood */
++ pData[5] = 50;
++ /* no current */
++ pData[6] = 0;
++ /* removable ports */
++ pData[7] = 0;
++ /* reserved */
++ pData[8] = 0xff;
++ wSize = pData[0];
++ break;
++ case GetHubStatus:
++ /* hub status */
++ memset(pData, 0, 4);
++ wSize = 4;
++ DBG("hub statusreport=%02x%02x%02x%02x\n",
++ pData[0], pData[1], pData[2], pData[3]);
++ break;
++ case GetPortStatus:
++ if (!wIndex || wIndex > ports)
++ goto error;
++ /* port status/change report */
++ memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2);
++ memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange), 2);
++ /* reset change (TODO: lock) */
++ pHub->aPortStatusChange[wIndex-1].wChange = 0;
++ wSize = 4;
++ DBG("port status report=%02x%02x%02x%02x\n",
++ pData[0], pData[1], pData[2], pData[3]);
++ break;
++
++ case SetHubFeature:
++ switch (wValue) {
++ case C_HUB_OVER_CURRENT:
++ case C_HUB_LOCAL_POWER:
++ break;
++ default:
++ goto error;
++ }
++ break;
++ case SetPortFeature:
++ if (!wIndex || wIndex > ports)
++ goto error;
++ switch (wValue) {
++ case USB_PORT_FEAT_SUSPEND:
++ DBG("suspend port %d\n", bPort);
++ pHub->pPortServices->pfSetPortSuspend(
++ pHub->pPortServices->pPrivateData, bPort, TRUE);
++ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND;
++ pHub->bIsChanged = TRUE;
++ wSize = 0;
++ break;
++ case USB_PORT_FEAT_POWER:
++ DBG("power port %d\n", bPort);
++
++ #if 1
++ {
++ int err;
++ err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_0,STMPE2401_PRIMARY_FUNCTION);
++ if (err != STMPE2401_OK)
++ DBG("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_0);
++ err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_0,STMPE2401_GPIO_OUT );
++ if (err != STMPE2401_OK)
++ DBG("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_0);
++ err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_0, 0);
++ if (err != STMPE2401_OK)
++ DBG("Couldn't set STMPE GPIO12\n");
++
++ }
++ #endif
++ pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData,
++ bPort,TRUE);
++ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER;
++ wSize = 0;
++
++ break;
++ case USB_PORT_FEAT_RESET:
++ DBG("USB_Class set feature USB_PORT_FEAT_RESET Port_no:%d \n",
++ bPort);
++ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET;
++ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
++ pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET;
++ pHub->bIsChanged = TRUE;
++
++ pHub->pPortServices->pfSetPortReset(
++ pHub->pPortServices->pPrivateData, bPort, TRUE);
++ wSize = 0;
++ break;
++ default:
++ goto error;
++ }
++ break;
++
++ default:
++error:
++ /* "protocol stall" on error */
++ retval = -EPIPE;
++ }
++
++ DBG("==> retval=%d\n", retval);
++ return retval;
++}
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_host.c
+@@ -0,0 +1,2791 @@
+/*
-+ * linux/drivers/usb/nomadik/musb_bus_direct.c
++ * linux/drivers/usb/nomadik/musb_host.c
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/usb.h>
++
++#include <asm/uaccess.h>
++
++#ifdef CONFIG_USB_DEBUG
++ #define DEBUG
++#else
++ #undef DEBUG
++#endif
++
++#include <linux/usb.h>
+
+#include "musbdefs.h"
-+#include <asm/io.h>
++#include "musb_host.h"
++#include "../core/hub.h"
+
-+#ifdef MUSB_BOARD_FILE
-+#include CONFIG_USB_INVENTRA_MUSB_BOARD_FILE
-+#else
-+#include "board.h"
++#ifdef MUSB_USE_HCD_DRIVER
++#define HAS_USB_TT_MULTI
++#include "../core/hcd.h"
+#endif
+
-+#ifndef MUSB_BOARD_DEFAULT_SIZE
-+#define MUSB_DEFAULT_ADDRESS_SPACE_SIZE 0x00001000
++/** how much to "scale" response timeouts */
++#define MUSB_MAX_RETRIES 8
++
++/*************************** Forwards ***************************/
++
++/* HCD helpers */
++static uint8_t find_first1(unsigned int nValue);
++static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
++static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
++static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis);
++int *Urb_test;
++extern int Urb_status;
++/**************************************************************************
++ *
++ **************************************************************************/
++
++#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY 0
+#endif
+
-+#ifdef MUSB_V26
-+#include <linux/device.h>
++#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN 0
+#endif
+
-+/****************************** sysfs stuff *****************************/
++#ifndef DEBUG
++#endif
+
-+#define kobj_to_direct_driver(obj) container_of(obj, struct device_driver, kobj)
-+#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
++int mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY;
+
-+/**************************** instance vars *****************************/
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE { }
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE { }
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP { }
+
-+#ifndef MUSB_USE_HCD_DRIVER
-+static int MGC_InstancesCount=0;
-+static MGC_LinuxCd** MGC_DriverInstances;
++/**************************************************************************
++ * Glue for virtual root hub
++**************************************************************************/
++
++#ifdef MUSB_CONFIG_PROC_FS
++/**
++ * Decode an host endpoint protocol.
++ * @param pUrn the uRb protocol shoudl be decoded
++ * @return a const char* to the name of the protocol.
++ */
++char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
++ char* pProto = "Err ";
++
++ switch(pThis->aLocalEnd[bEnd].bTrafficType) {
++ case PIPE_ISOCHRONOUS: pProto = "Isoc"; break;
++ case PIPE_INTERRUPT: pProto = "Intr"; break;
++ case PIPE_CONTROL: pProto = "Ctrl"; break;
++ case PIPE_BULK: pProto = "Bulk"; break;
++ }
++
++ return pProto;
++}
+#endif
+
-+void *g_pDevice;
-+/********************* under 26 thigs changes a bit *************************/
++/**
++ * Decode an urb protocol.
++ * @param pUrn the uRb protocol shoudl be decoded
++ * @return a const char* to the name of the protocol.
++ */
++char* decode_urb_protocol(struct urb* pUrb) {
++ static char buffer[8];
+
-+#ifdef MUSB_V26
-+#if 1
-+struct device MGC_ControllerDevice =
-+{
++ if ( !pUrb ) {
++ strcpy(&buffer[0], "NULL");
++ return buffer;
++ }
+
-+};
++ buffer[0]=usb_pipein(pUrb->pipe)?'I':'O';
++ if ( usb_pipeint(pUrb->pipe) ) {
++ strcpy(&buffer[1], " int");
++ } else if ( usb_pipeisoc(pUrb->pipe) ) {
++ strcpy(&buffer[1], " isoc");
++ } else if ( usb_pipebulk(pUrb->pipe) ) {
++ strcpy(&buffer[1], " bulk");
++ } else if ( usb_pipecontrol(pUrb->pipe) ) {
++ strcpy(&buffer[0], " ctl");
++ }
+
-+struct device_driver MGC_ControllerDriver=
-+{
-+ .name = "musb-hcd",
-+};
-+#endif
++ return buffer;
++}
+
-+#ifndef MUSB_USE_HCD_DRIVER
++/* Root speed need to be translated (addapted)
++ */
++static uint8_t MGC_TranslateVirtualHubSpeed(uint8_t source) {
++ uint8_t speed=2;
+
-+static inline ssize_t
-+store_new_id(struct device_driver *driver, const char *buf, size_t count);
++ switch ( source ) {
++ case 3: speed=0; break;
++ case 2: speed=1; break;
++ }
+
++ return speed;
++}
++
++/**
++ * Timer completion callback to turn off reset and get connection speed
++ */
++static void MGC_HdrcResetOff(unsigned long param)
++{
++ uint8_t power;
++ MGC_LinuxCd* pThis = (MGC_LinuxCd*)param;
++ void* pBase = pThis->pRegs;
++ unsigned long flags;
+
-+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
++ DBG(2, "<== Stopping root port reset...\n");
+
-+static ssize_t driver_count=0;
++ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++ pThis->bIgnoreDisconnect = FALSE;
++ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
+
-+/* probably we don't need to be a system device in this case */
-+struct device MGC_ControllerDevice =
-+{
++ /* check for high-speed and set in root device if so */
++ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++ if(power & MGC_M_POWER_HSMODE) {
++ DBG(3, "high-speed device connected\n");
++ pThis->bRootSpeed = 1;
++ }
+
-+};
++#ifdef MUSB_VIRTHUB
++ MGC_VirtualHubPortResetDone(&(pThis->RootHub), 0,
++ MGC_TranslateVirtualHubSpeed(pThis->bRootSpeed));
++#endif
+
-+struct device_driver MGC_ControllerDriver=
-+{
-+ .name = "musb-hcd",
-+};
++ DBG(2, "==>\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++}
+
-+/**
-+ * store_new_id
-+ *
-+ * Adds a new dynamic device ID to this driver,
-+ * and causes the driver to probe for all devices again.
-+ */
-+static inline ssize_t
-+store_new_id(struct device_driver *driver, const char *buf, size_t count)
++/* see virthub.h */
++void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bPower)
+{
-+ return driver_count++;
++ DBG(2, "<==\n");
++ if(bPower) {
++ DBG(3, "Root port power on\n");
++ MGC_HdrcStart((MGC_LinuxCd*)pPrivateData);
++ } else {
++ DBG(3, "Root port power off\n");
++ MGC_HdrcStop((MGC_LinuxCd*)pPrivateData);
++ }
++ DBG(2, "==>\n");
+}
+
-+
-+static ssize_t
-+direct_driver_attr_store(struct kobject * kobj, struct attribute *attr,
-+ const char *buf, size_t count)
++/* see virthub.h */
++void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bEnable)
+{
-+ struct device_driver *driver = kobj_to_direct_driver(kobj);
-+ struct driver_attribute *dattr = attr_to_driver_attribute(attr);
-+ ssize_t ret = 0;
++ DBG(2, "<==\n");
++ if (bEnable) {
++ DBG(3, "Root port power enabled\n");
++ } else {
++ DBG(3, "Root port power disabled\n");
++ }
+
-+ if (get_driver(driver)) {
-+ if (dattr->store)
-+ ret = dattr->store(driver, buf, count);
-+ put_driver(driver);
-+ }
-+ return ret;
++ DBG(2, "==>\n");
+}
+
-+static ssize_t
-+direct_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
++/* see virthub.h */
++void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bSuspend)
+{
-+ struct device_driver *driver = kobj_to_direct_driver(kobj);
-+ struct driver_attribute *dattr = attr_to_driver_attribute(attr);
-+ ssize_t ret = 0;
++ uint8_t power;
++ MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
++ void* pBase = pThis->pRegs;
+
-+ if ( get_driver(driver) ) {
-+ if (dattr->show)
-+ ret = dattr->show(driver, buf);
-+ put_driver(driver);
-+ }
-+ return ret;
-+}
++ DBG(2, "<==\n");
+
-+static struct sysfs_ops direct_driver_sysfs_ops = {
-+ .show = direct_driver_attr_show,
-+ .store = direct_driver_attr_store,
-+};
-+static struct kobj_type direct_driver_kobj_type = {
-+ .sysfs_ops = &direct_driver_sysfs_ops,
-+};
++ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++ if(bSuspend) {
++ DBG(3, "Root port power suspended\n");
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
++ } else if(power & MGC_M_POWER_SUSPENDM) {
++ DBG(3, "Root port power resumed\n");
++ power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME);
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
++ WAIT_MS(20);
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power);
++ }
+
-+static int
-+direct_create_newid_file(struct device_driver *drv)
-+{
-+ int error = 0;
-+ if (drv->probe != NULL)
-+ error = sysfs_create_file(&drv->kobj,
-+ &driver_attr_new_id.attr);
-+ return error;
++ DBG(2, "==>\n");
+}
+
-+static int
-+direct_populate_driver_dir(struct device_driver *drv)
++/* see virthub.h */
++void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bReset)
+{
-+ return direct_create_newid_file(drv);
-+}
++ uint8_t power;
++ MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
++ void* pBase = pThis->pRegs;
+
-+/* ------------------------ let the ball rolling -------------------------*/
++ DBG(2, "<==\n");
+
-+/* customize for different behavior */
-+static int direct_hotplug (struct device *dev, char **envp, int num_envp,
-+ char *buffer, int buffer_size)
-+{
-+ return -ENODEV;
++ power = MGC_Read8(pBase, MGC_O_HDRC_POWER) & 0xf0;
++ if (bReset) {
++ pThis->bIgnoreDisconnect = TRUE;
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESET);
++ MGC_LinuxSetTimer(pThis, MGC_HdrcResetOff, (unsigned long)pThis, 60);
++ } else if(power & MGC_M_POWER_RESET) {
++ DBG(3, "root port reset stopped\n");
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
++ }
++
++ DBG(2, "==>\n");
+}
+
-+static int direct_device_suspend(struct device * dev, u32 state)
-+{
-+ return 0;
++/**************************************************************************
++ *
++ **************************************************************************/
++
++ /**
++ * return the current urb for a given endpoint. Caller is responsible for
++ * locking
++ * @param pEnd the end point (pEnd!=NULL)
++ * @return the urb or NULL when the end point is idle
++ */
++struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd) {
++#ifdef MUSB_USE_HCD_DRIVER
++ return pEnd->pCurrentUrb;
++#else
++ DBG(8 ,"GetCurrentUrb urb_list_ptr:0x%p \n",&(pEnd->urb_list));
++ DBG(8 ,"GetCurrentUrb urb_list->next:0x%p \n",pEnd->urb_list.next);
++ DBG(8 ,"GetCurrentUrb urb_list->prev:0x%p \n",pEnd->urb_list.prev);
++ return list_empty(&(pEnd->urb_list)) ? NULL
++ : list_entry(pEnd->urb_list.next, struct urb, urb_list);
++#endif
+}
+
-+/* customize for different behavior */
-+static int direct_device_resume(struct device * dev)
++/**
++ * Test whether a local endpoint is idle.
++ * @param pEnd the endpoint
++ * @return !=0 when idle, 0 otherwise
++ */
++int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd)
+{
-+ return 0;
++#ifdef MUSB_USE_HCD_DRIVER
++ return (pEnd->pCurrentUrb)==NULL;
++#else
++ return list_empty(&pEnd->urb_list);
++#endif
+}
+
-+static int direct_bus_match(struct device * dev, struct device_driver * drv) {
-+ return (&MGC_ControllerDriver==drv)?1:0;
++
++void mgc_ep_idle(MGC_LinuxLocalEnd* pEnd) {
++#ifdef MUSB_USE_HCD_DRIVER
++ pEnd->pCurrentUrb=NULL;
++#else
++ INIT_LIST_HEAD(&(pEnd->urb_list));
++#endif
+}
+
-+struct bus_type direct_bus_type = {
-+ .name = "system",
-+ .match = direct_bus_match,
-+ .hotplug = direct_hotplug,
-+ .suspend = direct_device_suspend,
-+ .resume = direct_device_resume,
-+};
+
+/**
-+ * direct_register_driver - register a new driver
-+ * @drv: the driver structure to register
-+ *
-+ * Adds the driver structure to the list of registered drivers
-+ * Returns the number of devices which were claimed by the driver
-+ * during registration. The driver remains registered even if the
-+ * return value is zero.
++ * Dequeue an urb from an endpoint.
++ * @param pEnd the endpoint
++ * @param pUrb the urb to be removed
+ */
-+static int
-+direct_register_driver(struct device_driver *drv, struct bus_type *btype)
++static int mgc_ep_dequeue_urb(MGC_LinuxLocalEnd* pEnd, struct urb *pUrb,MGC_LinuxCd* pThis)
+{
-+ int count = 0;
-+
-+ /* initialize common driver fields */
-+ drv->bus = (btype)?btype:&direct_bus_type;
-+ drv->kobj.ktype = &direct_driver_kobj_type;
++ int rc=0;
+
-+ /* register with core */
-+ count = driver_register( drv );
-+ if (count >= 0) {
-+ direct_populate_driver_dir( drv );
-+ }
++#ifdef MUSB_USE_HCD_DRIVER
++ if ( pEnd->pCurrentUrb==pUrb ) {
++ pUrb->hcpriv=NULL;
++ pEnd->pCurrentUrb=NULL;
++ } else {
++ rc=-EINVAL;
++ ERR("*** Trying to dequeue pUrb=%p from ep%d while pEnd->pCurrentUrb=%p\n",
++ pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
++ }
++#else
++ pUrb->hcpriv=NULL;
++ list_del_init(&pUrb->urb_list);
++#endif
+
-+ return count ? count : 1;
++ /* clear endpoint status (preserving the softstate for find_end() ) */
++ mgc_ep_linux_clear(pEnd,pThis);
++
++ DBG(1, "==> dequeued pUrb=%p from pEnd->bEnd=%d rc=%d\n",
++ pUrb, pEnd->bEnd, rc);
++ return rc=0;
+}
+
+/**
-+ * unregister_driver - unregister a driver
-+ * @drv: the driver structure to unregister
-+ *
-+ * Deletes the driver structure from the list of registered drivers,
-+ * gives it a chance to clean up by calling its remove() function for
-+ * each device it was responsible for, and marks those devices as
-+ * driverless.
++ * @return 0 success, != when the ep is busy with another request
+ */
-+
-+static void
-+direct_unregister_driver(struct device_driver *drv)
++static int mgc_ep_enqueue_urb(MGC_LinuxLocalEnd* pEnd, struct urb* pUrb)
+{
-+ driver_unregister( drv );
-+}
++ int rc=0;
+
-+#endif
++#ifdef MUSB_USE_HCD_DRIVER
++ if ( pEnd->pCurrentUrb ) {
++ ERR("*** urb=%p, ep=%d wile busy with urb=%p, this is BAD (tm)\n",
++ pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
++ rc=-EBUSY;
++ } else {
++ pEnd->pCurrentUrb=pUrb;
++ }
++#else
++ list_add_tail(&(pUrb->urb_list), &(pEnd->urb_list));
+#endif
+
-+/* ------------------------------------------------------------------- */
-+/* ------------------------------------------------------------------- */
-+/* ------------------------------------------------------------------- */
++ return rc;
++}
+
-+#ifdef MUSB_CUSTOM_DIRECT_BUS_FILE
-+#include MUSB_CUSTOM_DIRECT_BUS_FILE
-+#else
+/**
-+ * Discover and initialize the drivers on the direct bus.
++ * find the end an urb is posted to
++ * @param pUrb
++ * @return the pEnd or NULL when not found.
+ */
-+int
-+direct_bus_init(void) {
-+
-+ int rc= -1;
-+ char name[32];
-+ void* pDevice = NULL;
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ MGC_LinuxCd* pThis;
-+
-+ /* already initialized */
-+ if ( MGC_nIndex ) {
-+ return 0;
-+ }
-+ snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
-+
-+ pDevice = &MGC_ControllerDevice;
-+ g_pDevice=pDevice;
-+ kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
-+
-+ rc = kobject_register(&((struct device*)pDevice)->kobj);
++MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb)
++{
++ int bEnd=0;
+
-+ if(rc < 0){
-+ ERR("failed to register:%d\n", rc);
-+ return rc;
++ for (bEnd=0; bEnd<MUSB_C_NUM_EPS-1; bEnd++) {
++ if ( MGC_GetCurrentUrb(&pThis->aLocalEnd[bEnd])==pUrb ) {
++ return &pThis->aLocalEnd[bEnd];
++ }
+ }
-+
-+ INIT_LIST_HEAD( (struct list_head*)&((struct device*)pDevice)->klist_children );
-+
-+ ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
-+
-+ sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);
-+
-+ pThis = MGC_LinuxInitController(pDevice, MUSB_CONTROLLER_HDRC, INT_USBOTG,
-+ ioremap(NOMADIK_USB_BASE, 0x100000), 0x00100000, name);
-+
-+ if(pThis) {
-+ DBG(3, "MGC_LinuxInitController success MGC_struct:0x%p \n", pThis);
-+ rc = 0;
-+ MGC_VirtualHubStart( &(pThis->RootHub) );
++
++ return NULL;
++}
++
++/**************************************************************************
++ *
++ **************************************************************************/
++
++void mgc_complete_urb(MGC_LinuxCd *pThis, struct urb *pUrb) {
++ /* give it back */
++ usb_put_urb(pUrb);
++ if (pUrb->status) {
++ DBG(1, "completing urb=%p,status=%d\n", pUrb, pUrb->status);
+ }
-+ return(rc);
-+
++
++#ifdef MUSB_USE_HCD_DRIVER
++ mgc_hcd_complete_urb(pThis, pUrb);
+#else
-+ const int nCount = sizeof(MUSB_aLinuxController)
-+ / sizeof(MUSB_LinuxController);
-+ int nIndex;
-+
-+ INFO("Probing direct bus [direct=%d]\n", nCount);
-+
-+ if ( !nCount ) {
-+ return 0;
-+ }
-+
-+ KMALLOC(MGC_DriverInstances, nCount*sizeof(MGC_LinuxCd*), GFP_ATOMIC);
-+ if ( !MGC_DriverInstances ) {
-+ return -ENOMEM;
-+ }
-+
-+#ifdef MUSB_V26
-+ pDevice = &MGC_ControllerDevice;
-+ kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
-+ rc = kobject_register(&((struct device*)pDevice)->kobj);
-+ if(rc < 0){
-+ ERR("failed to register:%d\n", rc);
-+ return rc;
++ if ( pUrb->complete ) {
++ COMPLETE_URB(pUrb, NULL);
+ }
-+
-+ INIT_LIST_HEAD( &((struct device*)pDevice)->children );
-+
-+ ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
-+ sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);
-+ bus_register( &direct_bus_type );
-+ direct_register_driver(&MGC_ControllerDriver, NULL);
-+#endif
-+
-+ /* NON PCI machines */
-+ for (nIndex = 0; !rc && nIndex < nCount; nIndex++) {
-+ MUSB_LinuxController* pStaticController=&(MUSB_aLinuxController[nIndex]);
-+
-+ snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
-+ MGC_DriverInstances[nIndex]=MGC_LinuxInitController(pDevice,
-+ pStaticController->wType, pStaticController->dwIrq,
-+ pStaticController->pBase,
-+ (pStaticController->dwSize)? pStaticController->dwSize
-+ : MUSB_DEFAULT_ADDRESS_SPACE_SIZE, name);
-+
-+ if( MGC_DriverInstances[nIndex] ) {
-+#ifdef MUSB_VIRTHUB
-+ MGC_VirtualHubStart( &(MGC_DriverInstances[nIndex]->RootHub) );
-+#endif
-+ MGC_InstancesCount++;
-+ } else {
-+ ERR("controller %d failed to initialize\n", nIndex);
-+ direct_bus_shutdown();
-+ rc=-1;
-+ }
-+ }
-+ return MGC_InstancesCount;
+#endif
-+
++
++ if (pUrb->status) {
++ DBG(1, "done completing pUrb=%p\n", pUrb);
++ }
+}
+
+/**
++ * complete an urb. Since urb completion generally post new urbs via
++ * submit urn, this make sure the ep won't kickstart it during the
++ * completion.
+ *
++ * @param pEnd the end point urb is posted to
++ * @param pUrb the urb to complete !=NULL
++ * @return 0 success
+ */
-+void direct_bus_shutdown(void)
++static inline int mgc_linux_complete_urb(MGC_LinuxCd *pThis,
++ MGC_LinuxLocalEnd* pEnd, struct urb *pUrb)
+{
-+#ifdef MUSB_USE_HCD_DRIVER
-+ kobject_unregister(&((struct device*)g_pDevice)->kobj); /* shoudl check the hcd drivers */
-+
-+
-+#else
-+ int nIndex=0;
-+
-+ /* free the instances */
-+ for (nIndex = 0; nIndex < MGC_InstancesCount; nIndex++) {
-+ MGC_LinuxCdFree( MGC_DriverInstances[nIndex] );
-+ }
-+
-+ KFREE(MGC_DriverInstances);
-+#ifdef MUSB_V26
-+ direct_unregister_driver(&MGC_ControllerDriver);
-+#endif
-+#endif
+
-+}
-+#endif
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_cross.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_cross.h
---- linux-2.6.20/drivers/usb/nomadik/musb_cross.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_cross.h 2008-08-08 19:15:22.000000000 +0530
-@@ -0,0 +1,131 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_cross.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
++ int periodic=mgc_urb_is_periodic(pUrb);
++ int status=periodic; /* 0 needs start next */
++ int error=(pUrb->status==-ENOENT) || (pUrb->status==-ECONNRESET) ||
++ (pUrb->status==-ESHUTDOWN) || (pUrb->status==-ETIMEDOUT)
++ || (pUrb->status==-EBUSY);
+
-+#ifndef __MUSB_CROSS_H
-+#define __MUSB_CROSS_H
++ DBG(2, "<== completing URB %p, on pEnd->bEnd=%d status=%d, proto=%s\n",
++ pUrb, pEnd->bEnd, pUrb->status, decode_urb_protocol(pUrb));
+
-+#include <linux/version.h>
++ if ( error && periodic ) {
++ pEnd->bIsClaimed=FALSE;
++ }
+
-+/****************************** KERNEL VERSION MACROS ************************/
++ /* prevents locking&kickstarting */
++ pEnd->bBusyCompleting=1;
+
-+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-+#undef MUSB_V26
++ mgc_complete_urb(pThis, pUrb);
+
-+#ifndef MUSB_V24
-+#define MUSB_V24
-+#endif
++#ifdef MUSB_V24
++ /* Under 2.4 interrupt IN URBs must be re-submitted from the driver
++ * unless they are unlinked; 2.6 urbs do that from the completition
++ * routine. ENODEV means we raced disconnect() */
++ if ( !error && periodic ) {
++ DBG(1, "periodic pUrb=%p, proto=%s, (status=%d)\n", pUrb,
++ decode_urb_protovol(pUrb), pUrb->status);
++ status=mgc_schedule_urb(pThis, pEnd, pUrb);
++ if ( (status!= 0) && (status != -ENODEV) ) {
++ DBG(3, "error resubmitting intr URB %p (status=%d)\n",
++ pUrb, status);
++ }
+
++ }
++#else
++ status=0; /* kickstart next */
+#endif
+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#undef MUSB_V24
-+#ifndef MUSB_V26
-+#define MUSB_V26
-+#endif
-+#endif
++ /* allows locking&kickstarting again */
++ pEnd->bBusyCompleting=0;
+
-+#ifdef MUSB_V26
++ DBG(2, "==> status=%d, periodic=%d\n", status, periodic);
++ return status;
++}
+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
-+#ifndef MUSB_V26_POST10
-+#define MUSB_V26_POST10
-+#endif
-+#endif
++/**
++ * Start transmit. Caller is responsible for locking the ep.
++ * On EP0 only PING is disabled.
++ *
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ */
++void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++ uint16_t wCsr;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++ DBG(2, "<== bEnd=%d ==>\n", bEnd);
++ /* NOTE: no locks here; caller should lock */
++ MGC_SelectEnd(pBase, bEnd);
++ if(bEnd) {
++ wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++ wCsr |= MGC_M_TXCSR_TXPKTRDY;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
++ } else {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_CSR0_H_NO_PING | MGC_M_CSR0_H_SETUPPKT | MGC_M_CSR0_TXPKTRDY);
++ }
++}
+
++/**************************************************************************
++ *
++ **************************************************************************/
+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
-+#ifndef MUSB_USE_HCD_DRIVER
-+#define MUSB_USE_HCD_DRIVER
-+#endif
++ /**
++ * return the buffer associated to an urb (map it too)
++ */
++static inline uint8_t* get_urb_buffer(struct urb* pUrb) {
++ uint8_t *pBuffer=NULL;
++
++#ifdef MUSB_PARANOID
++ if ( !pUrb ) {
++ return NULL;
++ }
+#endif
+
++ pBuffer=pUrb->transfer_buffer;
++#ifndef MUSB_LINUX_MV21
++ if ( !pBuffer ) {
++ pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
++ }
+#endif
+
++ return pBuffer;
++}
+
-+/*********************************** WEIRDNESS ******************************/
++/**
++ * Xmit a packet. pEnd->dwOffset is updated as well
++ * @param pThis
++ * @param bEnd the EP urb is queued to
++ */
++static uint8_t mgc_linux_packet_tx(MGC_LinuxCd* pThis, uint8_t bEnd) {
++ uint32_t wLength=0;
++ uint8_t bDone = FALSE;
++ uint8_t *pBase = (uint8_t*)pThis->pRegs;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++ struct urb* pUrb=MGC_GetCurrentUrb(pEnd);
++ uint8_t *pBuffer=get_urb_buffer(pUrb);
++ int nPipe = pUrb ? pUrb->pipe : 0;
+
-+#ifdef MUSB_V26_POST10
-+#define MUSB_MEMFLAG_TYPE unsigned int
++ DBG(2, "<== bEnd=%d\n", bEnd);
++
++ /* abort the transfer */
++ if ( !pBuffer ) {
++ ERR("***> no buffer was given, BAD things are happening (TM)!\n");
++ return TRUE;
++ }
++
++ /* see if more transactions are needed */
++#ifdef MUSB_DMA
++ if(pEnd->pDmaChannel) {
++ if (MGC_DMA_STATUS_FREE ==
++ pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel)
++ ) {
++ pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
++ }
++ } else {
++ pEnd->dwOffset += pEnd->dwRequestSize;
++ }
+#else
-+#define MUSB_MEMFLAG_TYPE int
++ pEnd->dwOffset += pEnd->dwRequestSize;
+#endif
+
-+/****************************** SYSTEM PROPERTIES ***************************/
++ if (usb_pipeisoc(nPipe)) {
++ /* isoch case */
++ if(++pEnd->dwIsoPacket >= pUrb->number_of_packets) {
++ bDone = TRUE;
++ } else {
++ pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
++ wLength = pUrb->iso_frame_desc[pEnd->dwIsoPacket].length;
++ }
++ } else {
++ pBuffer += pEnd->dwOffset;
++ wLength = min((uint32_t)(pEnd->wPacketSize),
++ (uint32_t)(pUrb->transfer_buffer_length - pEnd->dwOffset));
++ if(pEnd->dwOffset >= pUrb->transfer_buffer_length) {
++ /* sent everything; see if we need to send a null */
++ if(!((pEnd->dwRequestSize == pEnd->wPacketSize) &&
++ (pUrb->transfer_flags & USB_ZERO_PACKET)))
++ {
++ bDone = TRUE;
++ }
++ }
++ }
+
-+#if defined(MUSB_V26) || defined(MUSB_V24)
-+#define MUSB_HAS_BUSNAME
-+#endif
++ if (bDone) {
++ pUrb->status=0;
++ } else if ( wLength ) { /* @assert bDone && !wLength */
++ MGC_HdrcLoadFifo(pBase, bEnd, wLength, pBuffer);
++ pEnd->dwRequestSize = wLength;
++ }
+
-+#ifndef MUSB_LINUX_MV21
-+#define HAS_USB_TT_MULTI
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwTotalTxBytes += pEnd->dwRequestSize;
++ pEnd->dwTotalTxPackets++;
+#endif
+
-+#ifdef CONFIG_PREEMPT
-+/* warning??? */
-+#endif
++ DBG(2, "==> bDone=%d\n", bDone);
++ return bDone;
++}
+
-+/* gstorage is liked to the driver: the init code lives there */
-+#ifdef MUSB_GSTORAGE
-+#define MUSB_SKIP_INIT
-+#endif
+
-+/* When compiled in the kernel, the init function is needed only when gadget
-+ * gadget API is not compiled (usb_register_driver takes care of the init)
++/**
++ * Receive a packet (or part of it).
++ * @requires pThis->Lock locked
++ * @param pThis
++ * @param bEnd
++ * @param bIsochError
++ * @return TRUE if URB is complete
+ */
-+#if defined(MUSB_BUILTIN) && !defined(MUSB_GADGET)
-+#ifndef MUSB_SKIP_INIT
-+#define MUSB_SKIP_INIT
-+#endif
-+#endif
++static uint8_t mgc_linux_packet_rx(MGC_LinuxCd* pThis, uint8_t bEnd,
++ uint16_t wRxCount, uint8_t bIsochError)
++{
++ uint16_t wLength, wCsr;
++ uint8_t bDone = FALSE;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++ struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
++ uint8_t* pBuffer=get_urb_buffer(pUrb);
++ int nPipe = pUrb ? pUrb->pipe : 0;
+
-+/* -------------------------------- OTG ----------------------------- */
++ DBG(2, "<== end %d RxCount=%04x\n", bEnd, wRxCount);
+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-+#define MUSB_HAS_OTG
-+#define HAS_HNP_SUPPORT
-+#endif
++#ifdef MUSB_PARANOID
++ if ( !pUrb || ((pUrb->transfer_buffer_length - pEnd->dwOffset)<0) ) {
++ ERR("***> Rx error: pUrb=%p, pUrb->transfer_buffer_length=%d pEnd->dwOffset=%d\n", \
++ pUrb, pUrb->transfer_buffer_length, pEnd->dwOffset );
++ return TRUE;
++ }
++#endif
+
-+/* -------------------------------- DMA ----------------------------- */
++ DBG(3, "bEnd=%d, pUrb->transfer_flags=0x%x pUrb->transfer_buffer=%p\n", \
++ bEnd, pUrb->transfer_flags, pUrb->transfer_buffer);
++ DBG(3, "pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, wRxCount=%d\n",
++ pUrb->transfer_buffer_length, pEnd->dwOffset, wRxCount);
+
-+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
++ /* abort the transfer */
++ if ( !pBuffer ) {
++ ERR("***> pBuffer=NULL, BAD things are happening (TM)!\n");
++ return TRUE;
++ }
+
-+/* MVL21 doesn't support DMA */
-+#if defined(MUSB_LINUX_MV21)
-+#ifdef MUSB_DMA
-+#error "DMA Mode not supported in MontaVista 2.1"
-+#endif
++ /* unload FIFO */
++ if( usb_pipeisoc(nPipe) ) {
++ /* isoch case */
++ pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
++ wLength = min((unsigned int)wRxCount,
++ pUrb->iso_frame_desc[pEnd->dwIsoPacket].length);
++ pUrb->actual_length += wLength;
+
-+/* DMA supported from 2.4 'till 2.6.10 */
-+#elif defined(MUSB_V24) || (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
-+#ifndef MUSB_HAS_DMA_URBS
-+#define MUSB_HAS_DMA_URBS
-+#endif
++ /* update actual & status */
++ pUrb->iso_frame_desc[pEnd->dwIsoPacket].actual_length = wLength;
++ if(bIsochError) {
++ pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_CRC;
++ pUrb->error_count++;
++ } else {
++ pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_NOERROR;
++ }
+
-+/* DMA not supported on versions >= 2.6.10 */
-+#elif ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) )
++ /* see if we are done */
++ bDone = (++pEnd->dwIsoPacket >= pUrb->number_of_packets);
+
-+#ifdef MUSB_DMA
-+#error "DMA Mode MIGHT not be supported in kernels > 2.6.10"
-+#endif
++ DBG(3, "pEnd->dwIsoPacket=%d, pUrb->number_of_packets=%d, wLength=%d\n",
++ pEnd->dwIsoPacket, pUrb->number_of_packets, wLength);
++ DEBUG_CODE(3, if ( bDone ) { \
++ INFO("completing %d-packet isoch URB; len=%x, errors=%d\n", \
++ pUrb->number_of_packets, pUrb->actual_length, pUrb->error_count); \
++ } );
++ } else {
++ DBG(3, "(bEnd=%d), wRxCount=%d, pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, pEnd->wPacketSize=%d\n",
++ bEnd, wRxCount, pUrb->transfer_buffer_length, pEnd->dwOffset, pEnd->wPacketSize);
+
-+#endif
++ /* non-isoch */
++ pBuffer += pEnd->dwOffset;
++ wLength = min((unsigned int)wRxCount,
++ pUrb->transfer_buffer_length - pEnd->dwOffset);
++ pUrb->actual_length += wLength;
++ pEnd->dwOffset += wLength;
+
-+/* -------------------------------- GADGETS ----------------------------- */
-+#endif
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_debug.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_debug.c
---- linux-2.6.20/drivers/usb/nomadik/musb_debug.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_debug.c 2008-07-28 15:20:53.000000000 +0530
-@@ -0,0 +1,190 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_debug.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/completion.h>
-+#include <linux/interrupt.h>
++ /* see if we are done */
++ bDone = (pEnd->dwOffset >= pUrb->transfer_buffer_length)
++ || (wRxCount < pEnd->wPacketSize);
+
-+#include <linux/usb.h>
++ DEBUG_CODE(3, if ( bDone ) { \
++ INFO("will complete URB; pUrb=%p (%s) len=%x, errors=%d\n", \
++ pUrb, decode_urb_protocol(pUrb), pUrb->actual_length, \
++ pUrb->error_count); \
++ } );
++ }
+
-+#include "debug.h"
-+#include "musbdefs.h"
++ if ( wLength ) {
++ MGC_HdrcUnloadFifo(pBase, bEnd, wLength, pBuffer);
++ }
+
-+#define IPRINTF(_f, _m) printk(KERN_INFO "%s"_f, indent, _m)
-+#define isspace(c) (c==' ' || c=='\t')
-+#define LABEL KERN_INFO "dump: "
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwTotalRxBytes += wLength;
++ pEnd->dwTotalRxPackets++;
++#endif
+
-+/******************************************************************/
++ if( wRxCount <= wLength ) { /* test for short packet */
++ wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++ wCsr & ~MGC_M_RXCSR_RXPKTRDY);
++ }
++ if ( bEnd && bDone ) {
++ pUrb->status=0;
++ }
+
-+int MGC_DebugLevel=MUSB_DEBUG;
-+int MGC_DebugDisable=0;
++ DBG(2, "==> bDone=%d\n", bDone);
++ return bDone;
++}
+
-+/******************************************************************/
++/* *************************************************************************
++ *
++ **************************************************************************/
+
-+/* Decode CSR0 value to a string. Not reentrant
++/**
++ * Find first (lowest-order) 1 bit
++ * @param nValue value in which to search
++ * @return bit position (0 could mean no bit; caller should check)
+ */
-+char *decode_csr0(uint16_t csr0) {
-+ static char buf[64];
-+ sprintf(buf, "(%s%s%s%s)",
-+ csr0&MGC_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"",
-+ csr0&MGC_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"",
-+ csr0&MGC_M_CSR0_P_SENDSTALL ? "[stalled]":"",
-+ csr0&MGC_M_CSR0_P_DATAEND ? "[dataend]":"");
-+ return buf;
-+}
++static uint8_t find_first1(unsigned int nValue)
++{
++ uint8_t bResult;
++ unsigned int nWork = nValue;
+
-+/* Decode a value to binary.
-+ */
-+char *decode_bits(uint16_t value) {
-+ int i=0;
-+ static char buf[64];
-+
-+ for (; i<16;i++) {
-+ buf[15-i]=(value&(1<<i))?'1':'0';
++ for(bResult = 0; bResult < 32; bResult++) {
++ if(nWork & 1) {
++ return bResult;
++ }
++ nWork >>= 1;
+ }
-+
-+ return buf;
++
++ return bResult;
+}
+
-+/* Decode TXCSR register.
++/**
++ * @param nPipe
+ */
-+char *decode_txcsr(uint16_t txcsr) {
-+ static char buf[256];
-+ sprintf(buf, "%s (%s%s%s%s)",
-+ decode_bits(txcsr),
-+ txcsr&MGC_M_TXCSR_TXPKTRDY ? "[TXPKTRDY]":"",
-+ txcsr&MGC_M_TXCSR_AUTOSET ? "[MGC_M_TXCSR_AUTOSET]":"",
-+ txcsr&MGC_M_TXCSR_DMAENAB ? "[MGC_M_TXCSR_DMAENAB]":"",
-+ txcsr&MGC_M_TXCSR_DMAMODE ? "[MGC_M_TXCSR_DMAMODE]":"");
-+ return buf;
++static inline char *pipe_type(const unsigned int nPipe) {
++ if ( usb_pipeisoc(nPipe) ) {
++ return "isoc";
++ } else if ( usb_pipebulk(nPipe) ) {
++ return "bulk";
++ } else if ( usb_pipeint(nPipe) ) {
++ return "int";
++ } else {
++ return "cntl";
++ }
+}
+
-+/*
++/** Calculate the interval (or NAK limit for bulk) for isoc and
++ * inter requests.
++ * @param pUrb the urb interval should be determined for
++ * @return the interval
+ */
-+char *decode_devctl(uint16_t devctl) {
-+ return (devctl&MGC_M_DEVCTL_HM)?"host":"function";
-+}
++static uint8_t hdrc_interval(struct urb* pUrb) {
++ const unsigned int nPipe = pUrb->pipe;
++ uint8_t bInterval = (uint8_t)pUrb->interval;
+
++ if( usb_pipeint(nPipe) ) {
++ /* correct interval for high-speed */
++ if((USB_SPEED_HIGH == ((uint8_t)pUrb->dev->speed)) && (pUrb->interval > 255)) {
++ bInterval = find_first1(pUrb->interval);
++ }
++ } else {
++ /* normalize value */
++ if(pUrb->interval > 16) {
++ bInterval = find_first1(pUrb->interval);
++ }
+
-+/*
-+ */
-+char *decode_ep0stage(uint8_t stage) {
-+ static char buff[64];
-+ uint8_t stallbit=stage&MGC_END0_STAGE_STALL_BIT;
-+
-+ stage=stage&~stage&MGC_END0_STAGE_STALL_BIT;
-+ sprintf(buff, "%s%s", (stallbit)? "stall-" : "",
-+ (stage==MGC_END0_STAGE_SETUP)
-+ ? "setup" :
-+ (stage==MGC_END0_STAGE_TX)
-+ ? "tx" :
-+ (stage==MGC_END0_STAGE_RX)
-+ ? "rx" :
-+ (stage==MGC_END0_STAGE_STATUSIN)
-+ ? "statusin" :
-+ (stage==MGC_END0_STAGE_STATUSOUT)
-+ ? "statusout" : "error");
-+ return buff;
-+}
++ if(usb_pipeisoc(nPipe) && (bInterval < 1)) {
++ bInterval = 1;
++ }
++
++ if( usb_pipebulk(nPipe) && (bInterval < 2)) {
++ /* this is the NACK time */
++ bInterval = 0;/*16;*/
++ }
++ }
+
++ DBG(2, "pipe_type=%s bInterval=%d\n", pipe_type(nPipe), bInterval);
+
-+/*
++ return bInterval;
++}
++
++/**
++ * @param pUrb
+ */
-+void dump_urb (void *pUrb)
-+{
-+ struct urb* purb=(struct urb*)pUrb;
++static inline uint8_t hdrc_type(struct urb* pUrb) {
++ uint8_t bStdType = 0;
++ const unsigned int nPipe = pUrb->pipe;
+
-+ printk (LABEL "urb :%p\n", purb);
-+ printk (LABEL "urb_list :%s\n", dump_node(&purb->urb_list));
-+#ifdef V24
-+ printk (LABEL "next :%p\n", purb->next);
-+#endif
-+ printk (LABEL "dev :%p\n", purb->dev);
-+ printk (LABEL "pipe :%08X\n", purb->pipe);
-+ printk (LABEL "status :%d\n", purb->status);
-+ printk (LABEL "transfer_flags :%08X\n", purb->transfer_flags);
-+ printk (LABEL "transfer_buffer :%p\n", purb->transfer_buffer);
-+ printk (LABEL "transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-+ printk (LABEL "actual_length :%d\n", purb->actual_length);
-+ printk (LABEL "setup_packet :%p\n", purb->setup_packet);
-+ printk (LABEL "start_frame :%d\n", purb->start_frame);
-+ printk (LABEL "number_of_packets :%d\n", purb->number_of_packets);
-+ printk (LABEL "interval :%d\n", purb->interval);
-+ printk (LABEL "error_count :%d\n", purb->error_count);
-+ printk (LABEL "context :%p\n", purb->context);
-+ printk (LABEL "complete :%p\n", purb->complete);
++ if(usb_pipeisoc(nPipe)) {
++ bStdType = 1;
++ } else if(usb_pipeint(nPipe)) {
++ bStdType = 3;
++ } else if( usb_pipebulk(nPipe) ) {
++ bStdType = 2;
++ }
++
++ return bStdType;
+}
+
+/**
-+ * Dump core registers whose reads are non-destructive.
-+ * @param pThis
-+ * @param bEnd
++ * program hdrc_registers for the device address of a given urb.
++ * @param pTjos
++ * @param pUrb
++ * @param bEnd
++ * @param bXmt
+ */
-+void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd)
++static void hdrc_set_address(MGC_LinuxCd* pThis, struct urb* pUrb, uint8_t bEnd,
++ unsigned int bXmt)
+{
-+ MGC_SelectEnd(pBase, bEnd);
-+
-+ if(!bEnd) {
-+ printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n",
-+ MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_TYPE0, 0),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0));
-+ } else {
-+ printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n",
-+ bEnd,
-+ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
-+ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd));
-+ printk(KERN_INFO " RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n",
-+ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
-+ MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
-+ MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd),
-+ MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd));
-+ }
-+
-+ if( multipoint) {
-+ printk(KERN_INFO " TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n",
-+ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR)),
-+ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR)),
-+ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT)));
-+ printk(KERN_INFO " RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n",
-+ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR)),
-+ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR)),
-+ MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT)));
++#ifdef MUSB_LINUX_MV21
++ struct usb_device* pParent;
++#endif
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ uint8_t bAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
++ uint8_t bHubAddr = 0, bHubPort = 0, bIsMulti = FALSE;
++
++
++ /* NOTE: there is always a parent due to the virtual root hub */
++ bHubAddr = (uint8_t)pUrb->dev->parent->devnum;
++ /* but not if parent is our virtual root hub */
++ if(bHubAddr == pThis->RootHub.bAddress) {
++ bHubAddr = 0;
+ }
-+}
+
++#ifdef MUSB_LINUX_MV21
++ /* parent hub address */
++ pParent = pUrb->dev->parent;
+
-+/* list related */
++ /* this distribution doesn't support directly, so try to find ourselves */
++ if((USB_SPEED_HIGH!=((uint8_t)pUrb->dev->speed)) &&
++ (pParent->devnum != pThis->RootHub.bAddress))
++ {
++ int nChild;
++ struct usb_device* pDevice;
+
-+/*
-+ * NOT REENTRANT!
-+ */
-+char *dump_node(struct list_head *node) {
-+ static char buf[64];
-+ sprintf(buf, "[n=%p,p=%p]", node->next, node->prev);
-+ return buf;
-+}
++ /* walk up to first high-speed hub and remember our subtree's child */
++ pDevice = pUrb->dev;
++ while(pParent && (USB_SPEED_HIGH != pParent->speed) &&
++ (pParent->devnum != pThis->RootHub.bAddress))
++ {
++ pDevice = pParent;
++ pParent = pParent->parent;
++ }
+
++ if(pParent && (pParent->devnum != pThis->RootHub.bAddress)) {
++ /* correlate to port and check for multi-TT */
++ for(nChild = 0; nChild < pParent->maxchild; nChild++) {
++ if(pParent->children[nChild] == pDevice) {
++ bHubPort = nChild + 1;
++ bIsMulti = (2 == pParent->descriptor.bDeviceProtocol);
++ break;
++ }
++ }
++ }
++ }
++#else
++ /* if tt pointer, use its info */
++ if(pUrb->dev->tt) {
++ bHubPort = (uint8_t)pUrb->dev->ttport;
++#ifdef HAS_USB_TT_MULTI
++ bIsMulti = (uint8_t)pUrb->dev->tt->multi;
++#endif
++ }
++#endif
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbdefs.h ../new/linux-2.6.20/drivers/usb/nomadik/musbdefs.h
---- linux-2.6.20/drivers/usb/nomadik/musbdefs.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musbdefs.h 2008-08-08 19:15:30.000000000 +0530
-@@ -0,0 +1,828 @@
-+/*
-+ * linux/drivers/usb/nomadik/musbdefs.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
++ if ( bIsMulti ) {
++ bHubAddr |=0x80;
++ }
+
-+#ifndef __MUSB_MUSBDEFS_H__
-+#define __MUSB_MUSBDEFS_H__
++ /* tx address */
++ if(pThis->bIsMultipoint) {
++ /* target addr & hub addr/port */
++ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR),
++ bAddress);
++ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR),
++ bHubAddr);
++ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT),
++ bHubPort);
+
-+#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <linux/smp_lock.h>
-+#include <linux/errno.h>
++ /* also, try Rx (this is a bug ion the core: I always need to to do
++ * both (at least for ep0), needs to be changed when the core is
++ * fixed */
++ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR),
++ bAddress);
++ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR),
++ bHubAddr);
++ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT),
++ bHubPort);
++ } else {
++ /* non-multipoint core */
+
-+#ifdef MUSB_CONFIG_PROC_FS
-+#include <linux/fs.h>
-+#endif
++ MGC_Write8(pBase, 0x80 + 8*bEnd, bAddress);
++ MGC_Write8(pBase, 0x84 + 8*bEnd, bAddress);
+
-+/* useful for compiling across linux version & debug definitions */
-+#include "musb_cross.h"
-+#include "debug.h"
++ }
+
-+/* Board-specific definitions (hard-wired controller locations/IRQs) */
-+#include "plat_cnf.h"
-+#include "plat_arc.h"
-+#include "musbhdrc.h"
++ DBG(2, "end %d, device %d, parent %d, port %d, multi-tt: %d, speed:%d\n", \
++ bEnd, pUrb->dev->devnum, bHubAddr, bHubPort, bIsMulti, pUrb->dev->speed );
++}
++
++/**
++ * @param pThis
++ * @param pUrb
++ * @param bEnd
++ * @param bXmt
++ */
++static void hdrc_set_protocol(MGC_LinuxCd* pThis, struct urb* pUrb,
++ uint8_t bEnd, unsigned int bXmt)
++{
++ uint8_t reg;
++ uint8_t bStdType = hdrc_type(pUrb);
++ unsigned int nPipe = pUrb->pipe;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++ reg = (bStdType << 4 ) |
++ (((uint8_t)usb_pipeendpoint(nPipe)) & 0xf);
++ switch( ((uint8_t)pUrb->dev->speed) ) {
++ case USB_SPEED_LOW:
++ reg |= 0xc0;
++ break;
++ case USB_SPEED_FULL:
++ reg |= 0x80;
++ break;
++ default:
++ reg |= 0x40;
++ }
++
++ if ( bXmt ) {
++ if(bEnd) {
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd, reg);
++ } else if(pThis->bIsMultipoint) {
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
++ }
++ } else {
++ if(bEnd) {
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_RXTYPE, bEnd, reg);
++ } else if(pThis->bIsMultipoint) {
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
++ }
++ }
++}
+
-+/****************************** VERIFY THE DEFINES **************************
-+ * determine how to compile the driver; MUSB_GADGET->as gadget driver,
-+ * MUSB_HOST as host mode, MUSB_OTG -> otg mode (host and gadget)
-+ *
-+ * OTG => GADGET
-+ */
++static void mgc_hdrc_flush_fifo(MGC_LinuxCd* pThis, uint8_t bEnd, int rx)
++{
++ if ( rx ) {
++ /* twice in case of double packet buffering */
++ MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd,
++ MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++ MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd,
++ MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++ }
++}
+
-+#ifdef MUSB_GSTORAGE
++static void mgc_hdrc_flush_end(MGC_LinuxCd* pThis, uint8_t bEnd) {
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
+
-+/* for now */
-+#ifndef MUSB_OTG
-+#define MUSB_OTG
-+#endif
++ if(bEnd) {
++ /* general endpoint */
++ /* if not ready, flush and restore data toggle */
++ if(!pEnd->bIsReady && pThis->bIsMultipoint) {
++ pEnd->bIsReady = TRUE;
+
-+#endif
++ /* twice in case of double packet buffering */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++ MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++ MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG);
++ }
++ } else {
++ /* endpoint 0: just flush */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd,
++ MGC_M_CSR0_FLUSHFIFO);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd,
++ MGC_M_CSR0_FLUSHFIFO);
++ }
++}
+
-+#ifdef MUSB_OTG
-+#endif
-+#ifndef MUSB_HOST
-+#define MUSB_HOST
++/**
++ * Program an HDRC endpoint as per the given URB
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ * @param pURB URB pointer
++ * @param nOut zero for Rx; non-zero for Tx
++ * @param pBuffer buffer pointer
++ * @param dwLength how many bytes to transmit or expect to receive
++ */
++static void mgc_hdrc_program_end(MGC_LinuxCd* pThis, uint8_t bEnd,
++ struct urb* pUrb, unsigned int nOut, unsigned int bXmt,
++ uint8_t* pBuffer, uint32_t dwLength)
++{
++ uint16_t wIntrTxE;
++ uint8_t bDone = FALSE;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ unsigned int nPipe = pUrb->pipe;
++ uint16_t wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut);
++ uint8_t bIsBulk = usb_pipebulk(nPipe);
++ uint8_t bInterval=hdrc_interval(pUrb);
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++ uint8_t bStdType = hdrc_type(pUrb);
++ uint8_t bDmaOk=FALSE;
++#ifdef MUSB_DMA
++ MGC_DmaChannel* pDmaChannel;
++ MGC_DmaController* pDmaController;
+#endif
++ unsigned long flags;
+
-+#ifdef CONFIG_PROC_FS
-+#ifndef MUSB_CONFIG_PROC_FS
-+#define MUSB_CONFIG_PROC_FS
-+#endif
-+#endif
++ DBG(2, "<==(bEnd=%d, pUrb=%p) bRemoteAddress=%d\n", bEnd, pUrb, (uint8_t)usb_pipedevice(nPipe));
++ DBG(3, "end %d, device %d, speed:%d\n", bEnd, pUrb->dev->devnum,
++ pUrb->dev->speed );
+
-+#ifdef MUSB_PROC_TESTMUSB
++ /* prepare endpoint registers according to flags */
++ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++ MGC_SelectEnd(pBase, bEnd);
+
-+#ifndef CONFIG_PROC_FS
-+#error "TestMusb needs CONFIG_PROC_FS"
-+#endif
++ if ( bStdType==0 ) {
++ bXmt=TRUE;
++ }
+
-+#ifndef MUSB_HOST
-+#error "TestMusb needs HOST MODE"
-+#endif
++ hdrc_set_protocol(pThis, pUrb, bEnd, bXmt);
++ hdrc_set_address(pThis, pUrb, bEnd, bXmt);
+
-+#endif
+
-+#ifdef MUSB_HOST
-+#define MUSB_VIRTHUB
-+#endif
++#ifdef MUSB_DMA
++ pDmaController = pThis->pDmaController;
++ pDmaChannel = pEnd->pDmaChannel;
+
-+/************************* DEFINES DEPENDENT INCLUDES ************************/
++ if( !WANTS_DMA(pUrb) && pDmaChannel) {
++ /* release previously-allocated channel */
++ pDmaController->pfDmaReleaseChannel(pDmaChannel);
++ pEnd->pDmaChannel = NULL;
++ } else if( WANTS_DMA(pUrb) ) {
+
-+/* virtual hub */
-+#include "musb_virthub.h"
++ /* candidate for DMA */
++ if(pDmaController && !pDmaChannel) {
++ pDmaChannel = pEnd->pDmaChannel = pDmaController->pfDmaAllocateChannel(
++ pDmaController->pPrivateData, bEnd, nOut ? TRUE : FALSE,
++ bStdType, wPacketSize);
+
-+/****************************** USB CONSTANTS ********************************/
++ }
+
-+#ifndef USB_DT_DEVICE_QUALIFIER
-+#define USB_DT_DEVICE_QUALIFIER 6
++ if(pDmaChannel) {
++ pDmaChannel->dwActualLength = 0L;
++ pEnd->dwRequestSize = min(dwLength, pDmaChannel->dwMaxLength);
++ bDmaOk = pDmaController->pfDmaProgramChannel(pDmaChannel,
++ wPacketSize, pDmaChannel->bDesiredMode, DMA_BUFFER(pUrb),
++ pEnd->dwRequestSize);
++ if(!bDmaOk) {
++ pDmaController->pfDmaReleaseChannel(pDmaChannel);
++ pEnd->pDmaChannel = NULL;
++ }
++ }
++ }
+#endif
+
-+#ifndef USB_DT_DEVICE_QUALIFIER_SIZE
-+#define USB_DT_DEVICE_QUALIFIER_SIZE 10
-+#endif
++ if ( bXmt ) { /* transmit */
++ uint16_t wLoadCount=0;
++ uint16_t wCsr= MGC_M_TXCSR_MODE;
+
-+#ifndef USB_DT_OTHER_SPEED
-+#define USB_DT_OTHER_SPEED 7
-+#endif
++ if ( !bDmaOk ) {
++ if( bIsBulk && pThis->bBulkSplit ) {
++ wLoadCount = min((uint32_t)pEnd->wMaxPacketSizeTx, dwLength);
++ } else {
++ wLoadCount = min((uint32_t)wPacketSize, dwLength);
++ }
++ }
+
-+#ifndef USB_MAXCHILDREN
-+#define USB_MAXCHILDREN (16)
-+#endif
++ /* disable interrupt in case we flush */
++ wIntrTxE = MGC_Read16(pBase, MGC_O_HDRC_INTRTXE);
++ MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE & ~(1 << bEnd));
+
-+/****************************** DEBUG CONSTANTS ********************************/
++ /* data toggle, make sure nothing is there! */
++ mgc_hdrc_flush_end(pThis, bEnd);
+
-+#define MGC_PAD_FRONT 0xa5deadfe
-+#define MGC_PAD_BACK 0xabadcafe
-+#define MGC_TEST_PACKET_SIZE 53
++ if( bEnd) {
++ wCsr |= MGC_M_TXCSR_H_WR_DATATOGGLE;
++ if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 1)) {
++ wCsr |= MGC_M_TXCSR_H_DATATOGGLE;
++ } else {
++ wCsr &= ~MGC_M_TXCSR_H_DATATOGGLE;
++ }
+
-+/****************************** CONSTANTS ********************************/
++ /* protocol/endpoint/interval/NAKlimit */
++ if(bIsBulk && pThis->bBulkSplit) {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd,
++ wPacketSize |
++ ((pEnd->wMaxPacketSizeTx / wPacketSize) - 1) << 11);
++ } else {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, wPacketSize);
++ }
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, bInterval);
+
-+#if MUSB_DEBUG > 0
-+#define STATIC
-+#define MUSB_PARANOID
-+#else
-+#define STATIC static
++#ifdef MUSB_DMA
++ if (bDmaOk) {
++ wCsr |= (MGC_M_TXCSR_AUTOSET | MGC_M_TXCSR_DMAENAB |
++ (pDmaChannel->bDesiredMode ? MGC_M_TXCSR_DMAMODE : 0));
++ }
+#endif
+
-+#ifndef TRUE
-+#define TRUE 1
-+#endif
-+#ifndef FALSE
-+#define FALSE 0
-+#endif
++ mgc_linux_packet_tx(pThis, bEnd);
++ } else {
++ /* protocol/endpoint/interval/NAKlimit */
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, bInterval);
++ if ( wLoadCount ) {
++ pEnd->dwRequestSize = wLoadCount;
++ MGC_HdrcLoadFifo(pThis->pRegs, bEnd, wLoadCount, pBuffer);
++ }
++ }
+
-+#ifndef MUSB_C_NUM_EPS
-+#define MUSB_C_NUM_EPS ((uint8_t)16)
-+#endif
++ /* re-enable interrupt and write CSR to transmit */
++ MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE);
+
-+#ifndef MUSB_MAX_END0_PACKET
-+#define MUSB_MAX_END0_PACKET ((uint16_t)MGC_END0_FIFOSIZE)
-+#endif
++ if (bEnd) {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
++ }
++ } else { /* receive */
+
-+#define MGC_END0_START 0x0
-+#define MGC_END0_OUT 0x2
-+#define MGC_END0_IN 0x4
-+#define MGC_END0_STATUS 0x8
++ /* if was programmed for Tx, be sure it is ready for re-use */
++ uint16_t wCsr=MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++ if ( pEnd->bIsSharedFifo && wCsr & MGC_M_TXCSR_MODE) {
++ pEnd->bIsReady = FALSE;
+
-+#define MGC_END0_STAGE_SETUP 0x0
-+#define MGC_END0_STAGE_TX 0x2
-+#define MGC_END0_STAGE_RX 0x4
-+#define MGC_END0_STAGE_STATUSIN 0x8
-+#define MGC_END0_STAGE_STATUSOUT 0xf
-+#define MGC_END0_STAGE_STALL_BIT 0x10
++ DBG(1, "reprogramming ep%d for rx\n", bEnd);
+
-+/* obsolete */
-+#define MGC_END0_STAGE_DATAIN MGC_END0_STAGE_TX
-+#define MGC_END0_STAGE_DATAOUT MGC_END0_STAGE_RX
++ if ( wCsr & MGC_M_TXCSR_FIFONOTEMPTY ) {
++ /* this shouldn't happen */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++ MGC_M_TXCSR_FRCDATATOG);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++ MGC_M_TXCSR_FRCDATATOG);
+
-+/* EASY GUESS */
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-+#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus, _port)
-+#else
-+/* 2.4, mvl21, bc5 */
-+#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus)
-+#endif
++ ERR("*** switching end %d to Rx but Tx FIFO not empty\n", bEnd);
++ MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP;
++ }
+
++ /* clear mode (and everything else) to enable Rx */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 0);
++ }
+
-+/* 2.4/2.6 compatibility */
-+#ifdef MUSB_V26
++ /* grab Rx residual if any */
++ wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
++ if (wCsr & MGC_M_RXCSR_RXPKTRDY) {
++ uint16_t wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
++ bDone = mgc_linux_packet_rx(pThis, bEnd, wRxCount, FALSE);
++ DBG(1, "residual found bDone=%d\n", bDone);
++ }
+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
-+#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) ((_dev)->bus->op->disable(_dev, _pipe_ep))
-+#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
-+#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) ( 0 )
-+#else
-+#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
-+#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
-+#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
++ /* protocol/endpoint/interval/NAKlimit */
++ if(bEnd) {
++#if 0
++ /* doesn't work reliably */
++ if(bIsBulk && pThis->bBulkCombine) {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize |
++ ((min(pEnd->wMaxPacketSizeRx, dwLength) / wPacketSize) - 1) << 11);
++ } else {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize);
++ }
+#endif
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, bInterval);
++ }
+
-+/*#define COMPLETE_URB(_pUrb, _p) _pUrb->complete(_pUrb, _p)*/
-+#define COMPLETE_URB(_pUrb, _p) (_pUrb->complete=_p)
-+#define WAIT_MS(_ms) mdelay(_ms)
++ /* first time or re-program and shared FIFO, flush & clear toggle */
++ if(!pEnd->bIsReady && pEnd->bIsSharedFifo) {
++ DBG(4, "shared fifo\n");
+
-+#define USB_ISO_ASAP 0x0002
-+#define USB_ASYNC_UNLINK 0x0008
++ /* twice in case of double packet buffering */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++ MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++ MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++ pEnd->bIsReady = TRUE;
++ }
+
-+#define USB_ST_NOERROR (0)
-+#define USB_ST_CRC (-EILSEQ)
-+#define USB_ST_BITSTUFF (-EPROTO)
-+#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */
-+#define USB_ST_DATAOVERRUN (-EOVERFLOW)
-+#define USB_ST_DATAUNDERRUN (-EREMOTEIO)
-+#define USB_ST_BUFFEROVERRUN (-ECOMM)
-+#define USB_ST_BUFFERUNDERRUN (-ENOSR)
-+#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */
-+#define USB_ST_SHORT_PACKET (-EREMOTEIO)
-+#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */
-+#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */
-+#define USB_ST_URB_PENDING (-EINPROGRESS)
-+#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */
-+#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/
-+#define USB_ST_NOTSUPPORTED (-ENOSYS)
-+#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */
-+#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */
-+#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */
-+#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/
-+
-+#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs always with zero length packet */
++ /* program data toggle if possibly switching use */
++ if(!pEnd->bIsReady && pThis->bIsMultipoint) {
++ DBG(4, "multipoint\n");
+
-+#endif
++ wCsr = MGC_M_RXCSR_H_WR_DATATOGGLE;
++ if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 0)) {
++ wCsr |= MGC_M_RXCSR_H_DATATOGGLE;
++ }
+
-+#ifdef MUSB_V24
-+#define usb_disabled() 0
-+#define COMPLETE_URB(_pUrb, _p) _pUrb->complete(_pUrb)
-+#define WAIT_MS(_ms) wait_ms(_ms)
-+#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
-+#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr);
++ }
+
-+#ifdef MUSB_LINUX_MV21
-+#define usb_get_urb(_pUrb) _pUrb
-+#define usb_put_urb(_pUrb)
-+#undef MUSB_HAS_BUSNAME
++ /* kick things off */
++ if( bEnd && !bDone) {
++ wCsr = MGC_M_RXCSR_H_REQPKT;
++ if(usb_pipeint(nPipe)) {
++ wCsr |= MGC_M_RXCSR_DISNYET;
++ }
++#ifdef MUSB_DMA
++ if(bDmaOk) {
++ wCsr &= ~MGC_M_RXCSR_H_REQPKT;
++ wCsr |= MGC_M_RXCSR_H_AUTOREQ;
++ wCsr |= (MGC_M_RXCSR_AUTOCLEAR | MGC_M_RXCSR_DMAENAB |
++ (pDmaChannel->bDesiredMode ? MGC_M_RXCSR_DMAMODE : 0));
++ }
+#endif
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr);
++ }
++ }
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ DBG(2, "==>\n");
++}
+
-+#endif
++/* *************************************************************************
++ *
++ **************************************************************************/
+
-+typedef enum
++static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis)
+{
-+ MGC_STATE_DEFAULT,
-+ MGC_STATE_ADDRESS,
-+ MGC_STATE_CONFIGURED
-+} MGC_DeviceState;
-+
-+/* failure codes */
-+#define MUSB_ERR_WAITING 1
-+#define MUSB_ERR_VBUS -1
-+#define MUSB_ERR_BABBLE -2
-+#define MUSB_ERR_CORRUPTED -3
-+#define MUSB_ERR_IRQ -4
-+#define MUSB_ERR_SHUTDOWN -5
-+#define MUSB_ERR_RESTART -6
-+
-+/****************************** FUNCTIONS ********************************/
-+
-+#define KMALLOC(a,b,c) { lock_kernel(); a=kmalloc(b,c); unlock_kernel(); }
-+#define KFREE(p) { lock_kernel(); kfree(p); unlock_kernel(); }
-+
-+/*************************** REGISTER ACCESS ********************************/
++ uint16_t wVal=0;
++ unsigned long flags;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
+
-+/* indexed vs. flat register model */
-+#ifdef MUSB_FLAT_REG
-+#define MGC_SelectEnd(_pBase, _bEnd)
-+#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
-+ MGC_Read8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
-+#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
-+ MGC_Read16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
-+#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
-+ MGC_Write8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
-+#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
-+ MGC_Write16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
-+#else
-+#define MGC_SelectEnd(_pBase, _bEnd) \
-+ MGC_Write8(_pBase, MGC_O_HDRC_INDEX, _bEnd)
-+#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
-+ MGC_Read8(_pBase, (_bOffset + 0x10))
-+#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
-+ MGC_Read16(_pBase, (_bOffset + 0x10))
-+#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
-+ MGC_Write8(_pBase, (_bOffset + 0x10), _bData)
-+#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
-+ MGC_Write16(_pBase, (_bOffset + 0x10), _bData)
-+#endif
++ pEnd->dwOffset = 0;
++ pEnd->dwRequestSize = 0;
++ pEnd->dwIsoPacket = 0;
++ pEnd->dwWaitFrame = 0;
++ pEnd->bRetries = 0;
+
++ /* do the proper sequence to abort the transfer */
++ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
+
-+/************************** ULPI Registers ********************************/
++ MGC_SelectEnd(pBase, pEnd->bEnd);
+
-+/* Added in HDRC 1.9(?) & MHDRC 1.4 */
-+/* ULPI pass-through */
-+#define MGC_O_HDRC_ULPI_VBUSCTL 0x70
-+#define MGC_O_HDRC_ULPI_REGDATA 0x74
-+#define MGC_O_HDRC_ULPI_REGADDR 0x75
-+#define MGC_O_HDRC_ULPI_REGCTL 0x76
++ if((pEnd->bRemoteEnd & 0x0F) == 0)
++ {
++ wVal |= MGC_M_CSR0_FLUSHFIFO;
++ wVal &= ~MGC_M_CSR0_H_REQPKT;
++ wVal &= ~MGC_M_CSR0_TXPKTRDY;
+
-+/* extended config & PHY control */
-+#define MGC_O_HDRC_ENDCOUNT 0x78
-+#define MGC_O_HDRC_DMARAMCFG 0x79
-+#define MGC_O_HDRC_PHYWAIT 0x7A
-+#define MGC_O_HDRC_PHYVPLEN 0x7B /* units of 546.1 us */
-+#define MGC_O_HDRC_HSEOF1 0x7C /* units of 133.3 ns */
-+#define MGC_O_HDRC_FSEOF1 0x7D /* units of 533.3 ns */
-+#define MGC_O_HDRC_LSEOF1 0x7E /* units of 1.067 us */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wVal);
++ }
++ else
++ {
++ if(pEnd->bIsTx)
++ {
++ wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
++ wVal |= MGC_M_TXCSR_FLUSHFIFO;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, pEnd->bEnd, 0);
++ }
++ else
++ {
++ wVal &= ~MGC_M_RXCSR_H_REQPKT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, pEnd->bEnd, wVal);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, pEnd->bEnd, 0);
++ }
++ }
+
-+/* Added in HDRC 1.9(?) & MHDRC 1.4 */
-+/* ULPI */
-+#define MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND 0x02
-+#define MGC_M_ULPI_VBUSCTL_USEEXTVBUS 0x01
-+#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08
-+#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04
-+#define MGC_M_ULPI_REGCTL_COMPLETE 0x02
-+#define MGC_M_ULPI_REGCTL_REG 0x01
-+/* extended config & PHY control */
-+#define MGC_M_ENDCOUNT_TXENDS 0x0f
-+#define MGC_S_ENDCOUNT_TXENDS 0
-+#define MGC_M_ENDCOUNT_RXENDS 0xf0
-+#define MGC_S_ENDCOUNT_RXENDS 4
-+#define MGC_M_DMARAMCFG_RAMBITS 0x0f /* RAMBITS-1 */
-+#define MGC_S_DMARAMCFG_RAMBITS 0
-+#define MGC_M_DMARAMCFG_DMACHS 0xf0
-+#define MGC_S_DMARAMCFG_DMACHS 4
-+#define MGC_M_PHYWAIT_WAITID 0x0f /* units of 4.369 ms */
-+#define MGC_S_PHYWAIT_WAITID 0
-+#define MGC_M_PHYWAIT_WAITCON 0xf0 /* units of 533.3 ns */
-+#define MGC_S_PHYWAIT_WAITCON 4
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
+
-+/****************************** FUNCTIONS ********************************/
++#ifdef MUSB_USE_HCD_DRIVER
++ pEnd->pCurrentUrb=NULL;
++#endif
++}
+
-+#define MUSB_HST_MODE(_pthis) { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
-+ (_pthis)->bIsA=1; (_pthis)->bFailCode=0; }
-+#define MUSB_DEV_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
-+ (_pthis)->bIsA=0; (_pthis)->bFailCode=0; }
-+#define MUSB_B_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-+ (_pthis)->bIsA=0; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
-+#define MUSB_A_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-+ (_pthis)->bIsA=1; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
-+#define MUSB_ERR_MODE(_pthis, _cause) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-+ (_pthis)->bFailCode=_cause; }
++/**
++ * Start the current URB on an endpoint; wants ep to be
++ * locked and pThis to be locked as well; end must be claimed
++ * from the caller.
++ *
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ * @pre the endpoint is locked from the caller
++ * @pre pThis is NOT locked
++ */
++static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++ uint16_t wFrame;
++ uint32_t dwLength;
++ void* pBuffer;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++ struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
++ unsigned int nPipe, nOut, bXmt;
++ uint16_t wPacketSize;
++ uint8_t bRemoteAddress, bRemoteEnd;
+
-+#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
-+#define MUSB_IS_HST(_x) ( !MUSB_IS_ERR(_x) && (_x)->bIsHost && !(_x)->bIsDevice )
-+#define MUSB_IS_DEV(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && (_x)->bIsDevice )
-+#define MUSB_IS_B_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && !(_x)->bIsA )
-+#define MUSB_IS_A_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && (_x)->bIsA )
++ /* I should not have called!!! */
++ if ( !pUrb ) {
++ ERR("***> bEnd=%d is idle!\n", bEnd);
++ return;
++ }
+
-+#define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST":( MUSB_IS_DEV(_x)?"FUNCTION":(MUSB_IS_B_IDLE(_x)?"B_IDLE":(MUSB_IS_A_IDLE(_x)?"A_IDLE":"ERROR"))) )
++ if ( pUrb->hcpriv ) {
++ ERR("==> pUrb=%p, pUrb->hcpriv=%p, pEnd=%p, bEnd=%d (%s) was kickstarted already! this is not good (TM)\n",
++ pUrb, pUrb->hcpriv, pEnd, bEnd, decode_urb_protocol(pUrb));
++ }
+
-+#define HDRC_IS_HST(_x) ( MGC_Read8((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM )
-+#define HDRC_IS_DEV(_x) ( !HDRC_IS_HST(_x) )
++ nPipe = pUrb->pipe;
++ nOut = usb_pipeout(nPipe);
++ bXmt = nOut ? TRUE : FALSE;
++ wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut);
++ bRemoteAddress = (uint8_t)usb_pipedevice(nPipe);
++ bRemoteEnd = (uint8_t)usb_pipeendpoint(nPipe);
+
++ DBG(2, "<== pUrb=%p, bEnd=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, nOut=%d\n",
++ pUrb, bEnd, wPacketSize, bRemoteAddress, bRemoteEnd, nOut);
+
-+/******************************** DMA TYPES **********************************/
++ /* if no root device, assume this must be it */
++ if(!pThis->pRootDevice) {
++ pThis->pRootDevice = pUrb->dev;
++ switch(pThis->bRootSpeed) {
++ case 1:
++ pThis->pRootDevice->speed = USB_SPEED_HIGH;
++ break;
++ case 2:
++ pThis->pRootDevice->speed = USB_SPEED_FULL;
++ break;
++ case 3:
++ pThis->pRootDevice->speed = USB_SPEED_LOW;
++ break;
++ }
++ }
+
-+#ifdef MUSB_DMA
-+#include "dma.h"
++ /* indicate in progress */
++ pUrb->actual_length = 0;
++ pUrb->error_count = 0;
++ pUrb->hcpriv = pEnd;
++ /* remember software state - find_end() will use this - */
++ pEnd->bRemoteAddress = bRemoteAddress;
++ pEnd->bRemoteEnd = bRemoteEnd;
++ pEnd->bTrafficType = (uint8_t)usb_pipetype(nPipe);
++ pEnd->bIsTx=bXmt;
+
-+#ifndef MGC_HSDMA_CHANNELS
-+#define MGC_HSDMA_CHANNELS 8
-+#endif
++ /* init urb */
++ pEnd->dwOffset = 0;
++ pEnd->dwRequestSize = 0;
++ pEnd->dwIsoPacket = 0;
++ pEnd->dwWaitFrame = 0;
++ pEnd->bRetries = 0;
++ pEnd->wPacketSize = wPacketSize;
+
-+#ifdef MUSB_HAS_DMA_URBS
-+#define WANTS_DMA(_pUrb) ((_pUrb)->transfer_dma && (_pUrb->flags & URB_NO_TRANSFER_DMA_MAP))
-+#define DMA_BUFFER(_pUrb) ((_pUrb)->transfer_dma)
-+#else
-+#define WANTS_DMA(_pUrb) (0)
-+#define DMA_BUFFER(pUrb) ((void*)0x000666)
++#ifdef MUSB_USE_HCD_DRIVER
++ pEnd->pCurrentUrb=pUrb;
+#endif
+
-+extern MGC_DmaControllerFactory MGC_HdrcDmaControllerFactory;
-+#endif
++ /* pEnd->bIsClaimed=(usb_pipeisoc(nPipe) || usb_pipeint(nPipe)) ?TRUE:FALSE;
++ * end must be claimed from my caller
++ */
++ if( usb_pipecontrol(nPipe) ) {
++ /* control transfers always start with an OUT */
++ bXmt=TRUE;
++ pEnd->bIsTx=TRUE;
++ pThis->bEnd0Stage = MGC_END0_START;
++ }
+
++ /* gather right source of data */
++ if( usb_pipeisoc(nPipe) ) {
++ pBuffer = pUrb->transfer_buffer + pUrb->iso_frame_desc[0].offset;
++ dwLength = pUrb->iso_frame_desc[0].length;
++ } else if(usb_pipecontrol(nPipe)) {
++ pBuffer = pUrb->setup_packet;
++ dwLength = 8;
++ } else {
++ /* - */
++ pBuffer = pUrb->transfer_buffer;
++ dwLength = pUrb->transfer_buffer_length;
++ }
+
-+/************************** Ep Configuration ********************************/
++#ifndef MUSB_LINUX_MV21
++ if ( !pBuffer ) {
++ pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
++ }
++#endif
+
-+/** The End point descriptor */
-+struct MUSB_EpFifoDescriptor {
-+ uint8_t bType; /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */
-+ uint8_t bDir; /* 0 for autoconfig, INOUT, IN, OUT */
-+ uint16_t wSize; /* 0 for autoconfig, or the size */
-+ uint8_t bDbe; /* Double buffering: 0 disabled, 1 enabled */
-+};
++ /* abort the transfer */
++ if ( !pBuffer ) {
++ ERR("Rx requested but no buffer was given, BAD things are happening (TM)! aborting\n");
++ return;
++ }
+
-+#define MUSB_EPD_AUTOCONFIG 0
++ DBG(3, "(%p): dir=%s, type=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, pBuffer=%p\n", \
++ pUrb, (nOut)?"out":"in", usb_pipetype(nPipe), wPacketSize, bRemoteAddress,
++ bRemoteEnd, pBuffer);
+
-+#define MUSB_EPD_T_CNTRL 1
-+#define MUSB_EPD_T_ISOC 2
-+#define MUSB_EPD_T_BULK 3
-+#define MUSB_EPD_T_INTR 4
++ /* Configure endpoint */
++ mgc_hdrc_program_end(pThis, bEnd, pUrb, nOut, bXmt, pBuffer, dwLength);
+
-+#define MUSB_EPD_D_INOUT 0
-+#define MUSB_EPD_D_TX 1
-+#define MUSB_EPD_D_RX 2
++ /* if transmit, start it if it is time */
++ if ( !bXmt ) {
++ DBG(2, "==>\n");
++ return;
++ }
+
-+/******************************** TYPES *************************************/
++ /* determine if the time is right for a periodic transfer */
++ if( usb_pipeisoc(nPipe) || usb_pipeint(nPipe) ) {
++ DBG(3, "check whether there's still time for periodic Tx\n");
++ pEnd->dwIsoPacket = 0;
++ wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME);
+
-+struct urb;
-+struct usb_device;
-+struct usb_gadget;
-+struct usb_hcd;
++ if((pUrb->transfer_flags & USB_ISO_ASAP) ||
++ (wFrame >= pUrb->start_frame))
++ {
++ pEnd->dwWaitFrame = 0;
++ MGC_HdrcStartTx(pThis, bEnd);
++ } else {
++ pEnd->dwWaitFrame = pUrb->start_frame;
++ /* enable SOF interrupt so we can count down */
++ MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xff);
++ }
++ } else {
++ MGC_HdrcStartTx(pThis, bEnd);
++ }
+
-+/**
-+ * The device request.
-+ */
-+typedef struct __attribute__((packed)) {
-+ uint8_t bmRequestType;
-+ uint8_t bRequest;
-+ uint16_t wValue;
-+ uint16_t wIndex;
-+ uint16_t wLength;
-+} MUSB_DeviceRequest;
++ DBG(2, "==>\n");
++}
+
+/**
-+ * MGC_LinuxLocalEnd.
-+ * Local endpoint resource.
-+ * @field Lock spinlock
-+ * @field pUrb current URB
-+ * @field urb_list list
-+ * @field dwOffset current buffer offset
-+ * @field dwRequestSize how many bytes were last requested to move
-+ * @field wMaxPacketSizeTx local Tx FIFO size
-+ * @field wMaxPacketSizeRx local Rx FIFO size
-+ * @field wPacketSize programmed packet size
-+ * @field bIsSharedFifo TRUE if FIFO is shared between Tx and Rx
-+ * @field bAddress programmed bus address
-+ * @field bEnd programmed remote endpoint address
-+ * @field bTrafficType programmed traffic type
-+ * @field bIsClaimed TRUE if claimed
-+ * @field bIsTx TRUE if current direction is Tx
-+ * @field bIsReady TRUE if ready (available for new URB)
++ * Start the next URB on an endpoint. Wants the _endpoint_ to be locked.
++ * It might call MGC_LinuxStartUrb pThis needs to be locked as well..
++ * THIS UNLOCK THE END POINT.
++ *
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
+ */
-+typedef struct
++static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd)
+{
-+#if MUSB_DEBUG > 0
-+ uint32_t dwPadFront;
-+#endif
-+ spinlock_t Lock;
-+ uint8_t bEnd; /* ep number */
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ struct urb* pCurrentUrb;
-+#else
-+ struct list_head urb_list;
-+#endif
-+
-+ uint8_t bBusyCompleting; /* TRUE on Tx when the current urb is completing */
-+
-+ unsigned int dwOffset; /* offset int the current request */
-+ unsigned int dwRequestSize; /* request size */
-+ unsigned int dwIsoPacket;
-+ unsigned int dwWaitFrame;
-+ uint8_t bRetries;
-+
-+#ifdef MUSB_DMA
-+ MGC_DmaChannel* pDmaChannel;
-+#endif
++#ifndef MUSB_USE_HCD_DRIVER
++ struct urb* pUrb;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
+
-+#ifdef MUSB_CONFIG_PROC_FS
-+ unsigned long dwTotalTxBytes;
-+ unsigned long dwTotalRxBytes;
-+ unsigned long dwTotalTxPackets;
-+ unsigned long dwTotalRxPackets;
-+ unsigned long dwErrorTxPackets;
-+ unsigned long dwErrorRxPackets;
-+ unsigned long dwMissedTxPackets;
-+ unsigned long dwMissedRxPackets;
-+#endif
++ DBG(1, "<== bEnd=%d\n", bEnd);
++ pUrb=MGC_GetCurrentUrb(pEnd);
++ if ( !pUrb ) {
++ DBG(2, "==> bEnd=%d idle\n", bEnd);
++ return;
++ }
+
-+ uint16_t wMaxPacketSizeTx;
-+ uint16_t wMaxPacketSizeRx;
-+ uint16_t wPacketSize;
-+ uint8_t bDisableDma; /* not used now! */
-+ uint8_t bIsSharedFifo;
-+
-+ /* softstate, used from find_end() to determine a good match */
-+ uint8_t bRemoteAddress;
-+ uint8_t bRemoteEnd;
-+ uint8_t bTrafficType;
-+ uint8_t bIsClaimed; /* only for isoc and int traffic */
-+ uint8_t bIsTx;
-+ uint8_t bIsReady;
-+ uint8_t bStalled; /* the ep has been halted */
++ /* introduce a delay between urbs, to accomodate slow devices. The counter
++ * is increased on every NAK/TIMEOUT and decreased on successful transfers
++ * (eps != 0 )
++ */
++ if ( mgc_slow_device_kludge_delay ) {
++ DBG(1, "Delay mgc_slow_device_kludge_delay=%d\n",
++ mgc_slow_device_kludge_delay);
++ udelay( mgc_slow_device_kludge_delay*20 );
++ }
+
-+#if MUSB_DEBUG > 0
-+ uint32_t dwPadBack;
++ /* check for linked URB and jump start the next one */
++ mgc_linux_kickstart_urb(pThis, bEnd);
++#else
++ DBG(1, "<== bEnd=%d\n", bEnd);
++ if ( MUSB_IS_HST(pThis) ) {
++ mgc_hcd_schedule_urb(pThis);
++ }
+#endif
-+} MGC_LinuxLocalEnd;
-+
-+/** A listener for disconnection */
-+typedef void (*MGC_pfDisconnectListener)(void*);
-+/** A handler for the default endpoint interrupt */
-+typedef void (*MGC_pfDefaultEndHandler)(void*);
++ DBG(1, "==>\n");
++}
+
-+#ifdef MUSB_USE_HCD_DRIVER
-+typedef struct {
-+ spinlock_t urb_queue_lock;
-+ int urb_queue_count;
-+ int urb_exec_count;
-+ void *urb_queue_head;
-+ void *urb_queue_tail;
-+} mgc_hcd_urb_queue;
-+#endif
++/* *************************************************************************
++ *
++ **************************************************************************/
+
+/**
-+ * MGC_LinuxCd.
-+ * Driver instance data.
-+ * @field Lock spinlock
-+ * @field Timer interval timer for various things
-+ * @field pBus pointer to Linux USBD bus
-+ * @field RootHub virtual root hub
-+ * @field PortServices services provided to virtual root hub
-+ * @field pRootDevice root device pointer, to track connection speed
-+ * @field nIrq IRQ number (needed by free_irq)
-+ * @field bIsMultipoint TRUE if multi-point core
-+ * @field bIsHost TRUE if host
-+ * @field bIsDevice TRUE if peripheral
-+ * @field pRegs pointer to mapped registers
++ * Try to stop traffic on the given local endpoint. Don;t worry about the
++ * urbs, they will be flushed from the system (later on).
++ *
++ * @param pThis the controller
++ * @param bEnd the endpoint number.
+ */
-+typedef struct
++void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd)
+{
-+#if MUSB_DEBUG > 0
-+ uint32_t dwPadFront;
-+#endif
-+ spinlock_t Lock;
-+ struct timer_list Timer;
-+ struct usb_bus *pBus;
-+ char aName[32];
-+ MGC_VirtualHub RootHub;
-+ MGC_PortServices PortServices;
-+ struct usb_device* pRootDevice;
++ uint16_t wCsr;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ const uint8_t reg=(bEnd)?MGC_O_HDRC_RXCSR:MGC_O_HDRC_CSR0;
+
-+#ifdef MUSB_DMA
-+ MGC_DmaController* pDmaController;
-+#endif
++ DBG(2, "<== ep%d\n", bEnd);
++ wCsr = MGC_ReadCsr16(pBase, reg, bEnd);
++ wCsr &= (bEnd)?~MGC_M_RXCSR_H_REQPKT:~MGC_M_CSR0_H_REQPKT;
++ MGC_WriteCsr16(pBase, reg, bEnd, wCsr);
++ DBG(2, "==>\n");
++}
+
-+ int nIrq;
-+ int nIrqType;
-+
-+ int nBabbleCount;
-+ void* pRegs;
++/* *************************************************************************
++ *
++ **************************************************************************/
+
-+ MGC_LinuxLocalEnd aLocalEnd[MUSB_C_NUM_EPS];
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ mgc_hcd_urb_queue LocalQueue;
-+ wait_queue_head_t waitqh;
-+#endif
-+
-+ uint16_t wEndMask;
-+ uint8_t bEndCount;
-+ uint8_t bRootSpeed;
-+ uint8_t bIsMultipoint;
-+ uint8_t bIsHost;
-+ uint8_t bIsDevice;
-+ uint8_t bIsA;
-+ uint8_t bIgnoreDisconnect; /* during bus resets I got fake disconnects */
-+ uint8_t bVbusErrors; /* bus errors found */
-+
-+ int bFailCode; /* one of MUSB_ERR_* failure code */
-+
-+ uint8_t bBulkTxEnd;
-+ uint8_t bBulkRxEnd;
-+ uint8_t bBulkSplit;
-+ uint8_t bBulkCombine;
++/**
++ * Service the default endpoint (ep0) as host.
++ * @param pThis this
++ * @param wCount current byte count in FIFO
++ * @param pUrb URB pointer for EP0
++ * @return TRUE if more packets are required for this transaction
++ */
++static uint8_t mgc_hdrc_service_host_default(MGC_LinuxCd* pThis,
++ uint16_t wCount, struct urb* pUrb)
++{
++ uint8_t bMore = FALSE;
++ uint8_t* pFifoDest = NULL;
++ uint16_t wFifoCount = 0;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]);
++ MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;
+
-+ uint8_t bEnd0Stage; /* end0 stage while in host or device mode */
++ DBG(2, "<== (wCount=%04x, pUrb=%lx, bStage=%02x)\n",
++ wCount, (unsigned long)pUrb, pThis->bEnd0Stage);
+
-+#ifdef MUSB_GADGET
-+ uint8_t bDeviceState;
-+ uint8_t bIsSelfPowered;
-+ uint8_t bSetAddress;
-+ uint8_t bAddress;
-+ uint8_t bTestMode;
-+ uint8_t bTestModeValue;
++ if(MGC_END0_IN == pThis->bEnd0Stage) {
++ /* we are receiving from peripheral */
++ pFifoDest = pUrb->transfer_buffer + pUrb->actual_length;
++ wFifoCount = min(wCount, ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length)));
+
-+ struct usb_gadget* pGadget; /* the gadget */
-+ struct usb_gadget_driver* pGadgetDriver; /* it's driver */
++ DBG(3, "Receiving %d bytes in &%p[%d] (pUrb->actual_length=%u)\n",
++ wFifoCount, pUrb->transfer_buffer, (unsigned int)pUrb->actual_length,
++ pUrb->actual_length );
+
-+ /* Endpoint 0 buffer and its buffer code; can be customized for
-+ * devices that are not usign the default USB headers. Default
-+ * values are:
-+ *
-+ * . pfFillBuffer is MGC_HdrcReadUSBControlRequest()
-+ * . pEnd0Buffer is an instance of MGC_End0Buffer
-+ **/
-+ int (*pfReadHeader)(void*, uint16_t); /* NULL==MGC_HdrcReadUSBControlRequest*/
-+ void* pEnd0Buffer; /* this is the buffer, default implementation uses MGC_End0Buffer */
++ MGC_HdrcUnloadFifo(pBase, 0, wFifoCount, pFifoDest);
+
-+ /* compatibility, need to be osoleted used from gstorage */
-+ uint16_t wEnd0Offset;
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwTotalRxBytes += wFifoCount;
++ pEnd->dwTotalRxPackets++;
+#endif
+
-+#ifdef MUSB_OTG
-+ MGC_OtgMachine OtgMachine;
-+ MGC_OtgServices OtgServices;
-+ uint8_t bDelayPortPowerOff;
-+ uint8_t bOtgError;
-+#endif
++ pUrb->actual_length += wFifoCount;
++ if((pUrb->actual_length < pUrb->transfer_buffer_length) &&
++ (wCount == pEnd->wPacketSize))
++ {
++ bMore = TRUE;
++ }
++ } else {
++ /* we are sending to peripheral */
++ if((MGC_END0_START == pThis->bEnd0Stage) &&
++ (pRequest->bmRequestType & USB_DIR_IN))
++ {
++ DBG(3, "just did setup, switching to IN\n");
+
-+#if MUSB_DEBUG > 0
-+ uint32_t dwPadBack;
-+#endif
++ /* this means we just did setup; switch to IN */
++ pThis->bEnd0Stage = MGC_END0_IN;
++ bMore = TRUE;
+
+#ifdef MUSB_CONFIG_PROC_FS
-+ struct proc_dir_entry* pProcEntry;
-+
-+ /* A couple of hooks to enable HSET */
-+ MGC_pfDisconnectListener pfDisconnectListener;
-+ void* pDisconnectListenerParam;
-+ MGC_pfDefaultEndHandler pfDefaultEndHandler;
-+ void* pDefaultEndHandlerParam;
++ pEnd->dwTotalTxBytes += 8;
++ pEnd->dwTotalTxPackets++;
+#endif
++ } else if(pRequest->wLength && (MGC_END0_START == pThis->bEnd0Stage)) {
++ pThis->bEnd0Stage = MGC_END0_OUT;
++ pFifoDest = (uint8_t*)(pUrb->transfer_buffer + pUrb->actual_length);
++ wFifoCount = min(pEnd->wPacketSize,
++ ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length)));
++ DBG(3, "Sending %d bytes to %p\n", wFifoCount, pFifoDest);
++ MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoDest);
+
-+} MGC_LinuxCd;
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+void mgc_hcd_complete_urb(MGC_LinuxCd *pThis, struct urb* pUrb);
-+mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis);
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwTotalTxBytes += wFifoCount;
++ pEnd->dwTotalTxPackets++;
+#endif
++ pEnd->dwRequestSize = wFifoCount;
++ pUrb->actual_length += wFifoCount;
++ if(wFifoCount) {
++ bMore = TRUE;
++ }
++ }
++ }
++
++ return bMore;
++}
+
++/* *************************************************************************
++ * Default end (end 0)
++ **************************************************************************/
+
-+/***************************** Glue it together *****************************/
++/**
++ * Handle default endpoint interrupt as host. Only called in IRQ time
++ * from the LinuxIsr() interrupt service routine.
++ * @param pThis this
++ */
++void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis)
++{
++ struct urb* pUrb;
++ unsigned long flags;
++ uint16_t wCsrVal, wCount;
++ int status = USB_ST_NOERROR;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]);
++ uint8_t bVal, bOutVal = 0, bComplete = FALSE, bError = FALSE;
++ struct usb_descriptor_header *header;
++ MUSB_DeviceRequest* pRequest;
+
++ DBG(2, "<==\n");
+
-+extern unsigned int MGC_nIndex;
++ spin_lock(&pEnd->Lock);
++ pUrb = MGC_GetCurrentUrb(pEnd);
+
-+extern int MGC_DriverInit(void);
-+extern void MGC_DriverCleanup(void);
++ /* check URB */
++#ifdef MUSB_PARANOID
++ if( pUrb && (pUrb->hcpriv!=pEnd)) {
++ ERR("==> corrupt URB %p!!! from now on \"bad things will happen\"\n",
++ pUrb);
++ spin_unlock(&pEnd->Lock);
++ return;
++ }
++#endif
+
-+extern void MGC_HdrcStart(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcStop(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcServiceUsb(MGC_LinuxCd* pThis, uint8_t reg);
-+extern void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd,
-+ uint16_t wCount, const uint8_t* pSource);
-+extern void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd,
-+ uint16_t wCount, uint8_t* pDest);
++ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++ MGC_SelectEnd(pBase, 0);
++ wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0);
++ wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
++ bVal = (uint8_t)wCsrVal;
+
-+extern MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType,
-+ int nIrq, void* pRegs, u64 len, const char* pName);
-+extern void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long),
-+ unsigned long pParam, unsigned long millisecs);
++ DBG(2, "<== CSR0=%04x, wCount=%04x\n", wCsrVal, wCount);
+
-+extern void MGC_LinuxCdFree(MGC_LinuxCd* pThis);
++ /* if we just did status stage, we are done */
++ if(MGC_END0_STATUS == pThis->bEnd0Stage) {
++ bComplete = TRUE;
++ }
+
-+extern struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd);
++ /* prepare status */
++ if((MGC_END0_START == pThis->bEnd0Stage) && !wCount &&
++ (wCsrVal & MGC_M_CSR0_RXPKTRDY))
++ {
++ DBG(2, "missed data\n");
+
-+extern int queue_length(struct list_head *lh);
++ /* just started and got Rx with no data, so probably missed data */
++ status = USB_ST_SHORT_PACKET;
++ bError = TRUE;
+
-+/* Conditionally-compiled to update OTG state machine when necessary */
-+extern void MGC_OtgUpdate(MGC_LinuxCd* pThis, uint8_t bVbusError,
-+ uint8_t bConnect);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++ }
+
-+extern void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis);
-+extern MGC_LinuxCd *hcd_to_musbstruct(void *ptr);
-+extern struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis);
++ if(bVal & MGC_M_CSR0_H_RXSTALL) {
++ DBG(2, "STALLING ENDPOINT 0\n");
++ status = USB_ST_STALL;
++ bError = TRUE;
++ } else if(bVal & MGC_M_CSR0_H_ERROR) {
++ DBG(3, "ep0 no response (error)\n");
++ DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); );
+
-+/*-------------------------- available buses ---------------------*/
++ status = USB_ST_NORESPONSE;
++ bError = TRUE;
++ } else if(bVal & MGC_M_CSR0_H_NAKTIMEOUT) {
++ DBG(2, "ep0 NAK timeout pEnd->bRetries=%d\n", pEnd->bRetries);
+
-+extern int direct_bus_init(void);
-+extern void direct_bus_shutdown(void);
++ if( ++pEnd->bRetries < MUSB_MAX_RETRIES) {
++ /* cover it up if retries not exhausted */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
++ } else {
++ DBG(3, "no response (NAK timeout)\n");
++ DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); );
++ pEnd->bRetries=0;
++ status = USB_ST_NORESPONSE;
++ bError = TRUE;
++ }
++ }
+
-+/*-------------------------- ProcFS definitions ---------------------*/
++ if(USB_ST_NORESPONSE == status) {
++ DBG(2, "ep0 aborting\n");
+
-+struct MGC_TestProcData;
-+struct proc_dir_entry;
++ /* use the proper sequence to abort the transfer */
++ if(bVal & MGC_M_CSR0_H_REQPKT) {
++ bVal &= ~MGC_M_CSR0_H_REQPKT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++ bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++ } else {
++ bVal |= MGC_M_CSR0_FLUSHFIFO;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++ bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++ }
+
-+#ifdef MUSB_CONFIG_PROC_FS
-+extern char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
-+extern char* decode_dev_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
-+#endif
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, 0);
++ }
+
-+#ifdef MUSB_CONFIG_PROC_FS
-+extern void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
-+ MGC_pfDisconnectListener pfListener, void* pParam);
-+extern void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
-+ MGC_pfDefaultEndHandler pfHandler, void* pParam);
-+extern struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name,
-+ MGC_LinuxCd* data);
-+extern void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data);
-+#else
-+#define PROC_FS_DISABLED(_x) { DBG(3, "#PROC_FS DISABLED"); _x }
++ if(bError) {
++ DBG(3, "ep0 handling error\n");
+
-+static inline void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
-+ MGC_pfDisconnectListener pfListener, void* pParam) PROC_FS_DISABLED(;)
-+static inline void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
-+ MGC_pfDefaultEndHandler pfHandler, void* pParam) PROC_FS_DISABLED(;)
-+static inline struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name,
-+ MGC_LinuxCd* data) PROC_FS_DISABLED(;)
-+static inline void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data)
-+ PROC_FS_DISABLED(;)
++ /* clear it */
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
++
++#ifdef MUSB_CONFIG_PROC_FS
++ switch(pThis->bEnd0Stage) {
++ case MGC_END0_START:
++ case MGC_END0_OUT:
++ pEnd->dwErrorTxPackets++;
++ break;
++ case MGC_END0_IN:
++ pEnd->dwErrorRxPackets++;
++ break;
++ }
+#endif
+
-+/*-------------------------- TestProcFS definitions ---------------------*/
++ }
+
-+#ifdef MUSB_PROC_TESTMUSB
-+extern struct proc_dir_entry* MGC_LinuxCreateTestProcFs(char *name, MGC_LinuxCd* data);
-+extern void MGC_LinuxDeleteTestProcFs(char *name, MGC_LinuxCd* data);
-+#endif
++ if(!pUrb) {
++ /* stop endpoint since we have no place for its data, this
++ * SHOULD NEVER HAPPEN! */
++ DBG(1, "no URB for end 0\n");
+
-+/*------------------------------ IOCTLS/PROCFS -----------------------*/
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
+
-+extern void MGC_Zap(MGC_LinuxCd* pThis); /* zap the driver */
-+extern void MGC_Session(MGC_LinuxCd* pThis); /* start a session */
-+extern void MGC_SetDebugLevel(int level); /* set the debug level */
-+extern int dump_header_stats(MGC_LinuxCd* pThis, char *buffer); /* compile options etc */
-+#ifdef MUSB_HOST
-+int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
-+#endif
++ /* start next URB that might be queued for it */
++ spin_unlock(&pEnd->Lock);
++ DBG(2, "==>\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ return;
++ }
+
++ if(!bComplete && !bError) {
+
++ /* call common logic and prepare response */
++ if( mgc_hdrc_service_host_default(pThis, wCount, pUrb) ) {
++ /* more packets required */
++ bOutVal = (MGC_END0_IN == pThis->bEnd0Stage) ?
++ MGC_M_CSR0_H_REQPKT : MGC_M_CSR0_TXPKTRDY;
++ DBG(3, "Need more bytes bOutVal=%04x\n", bOutVal);
++ } else {
++ /* data transfer complete; perform status phase */
++ bOutVal = MGC_M_CSR0_H_STATUSPKT |
++ (usb_pipeout(pUrb->pipe) ? MGC_M_CSR0_H_REQPKT :
++ MGC_M_CSR0_TXPKTRDY);
+
-+/*-------------------------- DEBUG Definitions ---------------------*/
++ /* flag status stage */
++ pThis->bEnd0Stage = MGC_END0_STATUS;
++ DBG(3, "Data transfer complete, status phase bOutVal=%04x\n", \
++ bOutVal);
++ }
++ }
+
++ /* write CSR0 if needed */
++ if(bOutVal) {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bOutVal);
++ }
+
-+#ifdef MUSB_PARANOID
-+#define MGC_HDRC_DUMPREGS(_t, _s) MGC_HdrcDumpRegs((_t)->pRegs, MUSB_IS_HST(_t) && _t->bIsMultipoint, _s)
-+#define MGC_ISCORRUPT(_x) mgc_is_corrupt((_x), __FUNCTION__,__LINE__)
++ /* call completion handler if done */
++ if(bComplete || bError) {
++ DBG(3, "completing cntrl URB %p, status=%d, len=%x\n", \
++ pUrb, status, pUrb->actual_length);
+
-+/**
-+ * Test whether the struct is corrupted.
-+ * @param pThis
-+ */
-+static inline uint8_t mgc_is_corrupt(MGC_LinuxCd* pThis, const char *function, int line) {
-+#ifdef MUSB_HOST
-+ uint8_t bEnd;
-+ MGC_LinuxLocalEnd* pEnd;
-+#endif
-+
-+ if(MGC_PAD_FRONT != pThis->dwPadFront) {
-+ printk(KERN_INFO"musb %s:%d: pThis front pad corrupted (%x)\n",
-+ function, line, pThis->dwPadFront);
-+ return TRUE;
-+ }
-+
-+ if(MGC_PAD_BACK != pThis->dwPadBack) {
-+ printk(KERN_INFO"musb %s:%d: pThis back pad corrupted (%x)\n",
-+ function, line, pThis->dwPadBack);
-+ return TRUE;
-+ }
++ /* Hub Class not supported */
++ if((pUrb->dev == pThis->pRootDevice))
++ {
++ pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;
+
-+#ifdef MUSB_HOST
-+ for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+
-+ if(MGC_PAD_FRONT != pEnd->dwPadFront) {
-+ printk(KERN_INFO"musb %s:%d: end %d front pad corrupted (%x)\n",
-+ function, line, bEnd, pEnd->dwPadFront);
-+ return TRUE;
++ if((USB_REQ_GET_DESCRIPTOR == pRequest->bRequest) &&
++ (USB_DIR_IN == pRequest->bmRequestType) &&
++ (USB_DT_DEVICE == pUrb->setup_packet[3]) &&
++ (pUrb->setup_packet[6] >= USB_DT_DEVICE_SIZE))
++ {
++
++ header = (struct usb_descriptor_header*)pUrb->transfer_buffer;
++ if((header->bDescriptorType == USB_DT_DEVICE) &&
++ (*((char*)pUrb->transfer_buffer + 4) == USB_CLASS_HUB))
++ {
++ printk("Hub Class NOT support \n");
++ /* Will pass error to upper stack */
++ status = -ENODEV;
++ }
++ }
+ }
-+
-+ if(MGC_PAD_BACK != pEnd->dwPadBack) {
-+ printk(KERN_INFO"musb %s:%d: end %d back pad corrupted (%x)\n",
-+ function, line, bEnd, pEnd->dwPadBack);
-+ return TRUE;
++ if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
++ spin_unlock(&pEnd->Lock);
++ pUrb->status = status;
++ if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 ) {
++ mgc_linux_start_next_urb(pThis, 0);
++ }
++ } else {
++ ERR("*** pUrb=%p is not queued to bEnd=%d\n", pUrb,
++ pEnd->bEnd);
+ }
++ } else {
++ spin_unlock(&pEnd->Lock);
+ }
-+#endif
+
-+#ifdef MUSB_GADGET
-+ /* do something about it */
-+#endif
-+
-+ return FALSE;
++ DBG(2, "==>\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
+}
+
-+#else
-+#define MGG_IsCorrupt(_x) (_x)
-+#define MGC_HDRC_DUMPREGS(_t, _s)
-+#endif
++/**************************************************************************
++ * EP1-n Tx and Rx data
++ **************************************************************************/
+
-+/* -------------------------- Host Definitions ------------------------ */
++static void complete_ep_urb(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd,
++ struct urb* pUrb, int toggle)
++{
+
-+#ifdef MUSB_HOST
-+extern void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis);
-+#endif
++ if (pUrb->status==USB_ST_STALL) {
++ toggle=0;
++ }
+
-+/* -------------------------- Gadget Definitions --------------------- */
++ /* save data toggle */
+
-+struct usb_ep;
++ usb_settoggle(pUrb->dev, pEnd->bEnd, (pEnd->bIsTx)?1:0, toggle);
++ /* we re-use bulk, so re-programming required */
++ pEnd->bIsReady = FALSE;
+
-+extern const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE];
++ if (pUrb->status) {
++ DBG(1, "completing Tx URB=%p, status=%d, len=%x\n", \
++ pUrb, pUrb->status, pUrb->actual_length);
++ }
+
-+#if defined(MUSB_GADGET) || defined(MUSB_V26)
-+void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma);
-+void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma);
-+#endif
++ if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
++ spin_unlock(&pEnd->Lock);
++ if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 ) {
++ mgc_linux_start_next_urb(pThis, pEnd->bEnd);
++ }
++ } else {
++ ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb,
++ pEnd->bEnd);
++ }
++}
+
-+#ifdef MUSB_GADGET
-+extern void* MGC_MallocEp0Buffer(const MGC_LinuxCd* pThis);
-+#endif
++/**
++ * Service a Tx-Available interrupt for the given endpoint.
+
-+/* Gadget functions */
-+#ifdef MUSB_GADGET
-+struct usb_gadget;
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ */
++void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++ int skip=0;
++ struct urb* pUrb;
++ unsigned long flags;
++ uint16_t wTxCsrVal, wVal=0;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
++ uint32_t dev_status = 0;
+
-+extern MGC_LinuxCd* MGC_GetDriverByName(const char *name);
-+extern int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd);
-+extern void mgc_init_gadget_endpoints(MGC_LinuxCd *pThis, struct usb_gadget *gadget);
-+extern void MGC_GadgetReset(MGC_LinuxCd* pThis);
-+extern void MGC_GadgetResume(MGC_LinuxCd* pThis);
-+extern void MGC_GadgetSuspend(MGC_LinuxCd* pThis);
-+extern void MGC_GadgetDisconnect(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
-+extern void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
++ DBG(1, "<==\n");
+
-+extern void dump_ep_status(MGC_LinuxCd* pThis);
-+extern void dump_ep_queue(int index, int verbose);
++ spin_lock(&pEnd->Lock);
++ pUrb = MGC_GetCurrentUrb(pEnd);
++ if ( !pUrb ) {
++ MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE;
++ spin_unlock(&pEnd->Lock);
++ DBG(2, "==> tx ep empty\n");
++ return;
++ }
+
-+/*
-+ * Gadget disabled
-+ */
-+#else
-+#define GADGET_DISABLED(_x) { DBG(0, "#GADGET DISABLED"); _x }
++ if ( !pUrb->hcpriv ) {
++ DBG(2, "==> kickstarting it\n");
++ mgc_linux_kickstart_urb(pThis, bEnd);
++ spin_unlock(&pEnd->Lock);
++ return;
++ }
+
-+static inline MGC_LinuxCd* MGC_GetDriverByName(const char *name)
-+ GADGET_DISABLED( return NULL; )
-+static inline int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd)
-+ GADGET_DISABLED( return -1; )
-+static inline void MGC_InitGadgetEndPoints(MGC_LinuxCd *pThis)
-+ GADGET_DISABLED(;)
-+static inline void MGC_GadgetReset(MGC_LinuxCd* pThis)
-+ GADGET_DISABLED(;)
-+static inline void MGC_GadgetResume(MGC_LinuxCd* pThis)
-+ GADGET_DISABLED(;)
-+static inline void MGC_GadgetSuspend(MGC_LinuxCd* pThis)
-+ GADGET_DISABLED(;)
-+static inline void MGC_GadgetDisconnect(MGC_LinuxCd* pThis)
-+ GADGET_DISABLED(;)
-+static inline void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis)
-+ GADGET_DISABLED(;)
-+static inline void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd)
-+ GADGET_DISABLED(;)
-+static inline void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
-+ GADGET_DISABLED(;)
++ if ( !MUSB_IS_HST(pThis) ) {
++ complete_ep_urb(pThis, pEnd, pUrb, 0);
++ return;
++ }
+
-+static inline void dump_ep_status(MGC_LinuxCd* pThis)
-+ GADGET_DISABLED(;)
-+static inline void dump_ep_queue(int index, int verbose)
-+ GADGET_DISABLED(;)
++
++ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++ MGC_SelectEnd(pBase, bEnd);
++
++ wVal = wTxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++
++#if MUSB_DEBUG > 0
++ /* check URB */
++ if( pUrb && (pUrb->hcpriv != pEnd) ) {
++ ERR("==> end %d has corrupt URB %lx!\n", bEnd, (unsigned long)pUrb);
++ spin_unlock(&pEnd->Lock);
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ return;
++ }
+#endif
+
++ DBG(3, "end %d wTxCsrVal=%04x\n", bEnd, wTxCsrVal);
+
-+#endif /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h
---- linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h 2008-09-17 13:23:33.000000000 +0530
-@@ -0,0 +1,48 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_epdescriptors.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
++ do {
++ uint32_t status = 0;
+
-+struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] = {
++ /* check for errors */
++ if(wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) {
++ pEnd->bStalled=TRUE;
++ DBG(1, "TX end %d stall\n", bEnd);
++ status = USB_ST_STALL;
++ MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
++ } else if(wTxCsrVal & MGC_M_TXCSR_H_ERROR) {
++ WARN("TX data error on ep=%d\n", bEnd);
++ status = USB_ST_NORESPONSE;
++ dev_status = status;
++ /* do the proper sequence to abort the transfer */
++ wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
++ wVal |= MGC_M_TXCSR_FLUSHFIFO;
+
-+{}, /* EP0 use the default */
-+{ MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
-+{ MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 },
-+{ MUSB_EPD_T_INTR, MUSB_EPD_D_RX, 512 }
-+};
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
+
-+/**
-+struct MGC_EpFifoDescriptor {
-+ uint8_t bType; 0 for autoconfig, CNTR, ISOC, BULK, INTR
-+ uint8_t bDir; 0 for autoconfig, INOUT, IN, OUT
-+ uint16_t wSize; 0 for autoconfig, or the size
-+ uint 8_t bDbe; double buffering 0 disabled, 1 enabled
-+};
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwErrorTxPackets++;
++#endif
++ }
++ else if( wTxCsrVal & MGC_M_TXCSR_H_NAKTIMEOUT ) {
++ /* cover it up if retries not exhausted */
++ if( pUrb->status==-EINPROGRESS && ++pEnd->bRetries < MUSB_MAX_RETRIES )
++ {
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++ MGC_M_TXCSR_TXPKTRDY);
+
-+#define MUSB_EPD_AUTOCONFIG 0
++ MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
++ DBG(2, "tx error on ep%d, mgc_slow_device_kludge_delay=%d\n",
++ bEnd, mgc_slow_device_kludge_delay);
++ spin_unlock(&pEnd->Lock);
++ DBG(2, "==> cover tx error\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ return;
++ }
+
-+#define MUSB_EPD_T_CNTRL 1
-+#define MUSB_EPD_T_ISOC 2
-+#define MUSB_EPD_T_BULK 3
-+#define MUSB_EPD_T_INTR 4
++ if ( pUrb->status==-EINPROGRESS ) {
++ status = -ECONNRESET;
++ }
+
-+#define MUSB_EPD_D_INOUT 0
-+#define MUSB_EPD_D_TX 1
-+#define MUSB_EPD_D_RX 2
-+*/
++ WARN("device not responding on ep=%d\n", bEnd);
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c
---- linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c 2008-07-28 15:20:55.000000000 +0530
-@@ -0,0 +1,429 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_epfifocfg.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
+
-+#include "musbdefs.h"
-+#include "musb_epdescriptors.h"
++ /* do the proper sequence to abort the transfer */
++ wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
++ wVal |= MGC_M_TXCSR_FLUSHFIFO;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, 0);
+
-+#ifdef MUSB_EPFIFOCONFIG_FILE
-+#include CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwErrorTxPackets++;
+#endif
++ pEnd->bRetries=0;
++ } else if( wTxCsrVal & MGC_M_TXCSR_FIFONOTEMPTY ) {
++ /* whopps, dbould buffering better be enabled */
++#ifdef MUSB_PARANOID
++ /* guess what?? */
++#endif
++ skip=TRUE;
++ break;
++ }
+
-+#define DYN_FIFO_SIZE (1<<(MUSB_C_RAM_BITS+2))
-+#define CONFIGURE_FIFO(_pThis, _pEnd, _Dsc, _wFifoOffset) \
-+ configure_fifo(_pThis, _pEnd, (_Dsc)->bDir, (_Dsc)->wSize, (_Dsc)->bDbe, _wFifoOffset)
-+
-+
-+/* force array based */
-+#ifdef MUSB_C_DYNFIFO_DEF
-+
-+#ifdef MUSB_EPDISCRIPTORS_FILE
-+/**
-+ * configure the fifo and make sure the pThis endmask is updated.
-+ *
-+ * @param pThis
-+ * @param pEnd the end to configure
-+ * @param bDir the direction (in, out, inout)
-+ * @param wSize the fifo size, real fifo size
-+ * @param bDbe double buffering enabled?
-+ * @param wFifoOffset the current offset
-+ */
-+static uint16_t configure_fifo(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd,
-+ uint8_t bDir, uint16_t wSize, uint8_t bDbe, uint16_t wFifoOffset)
-+{
-+ uint16_t offset=wSize;
-+ void* pBase = pThis->pRegs;
-+ uint8_t szValue=wSize>>3;
-+ uint16_t addValue=wFifoOffset>>3;
-+
-+ /* when double buffering is enabled endpoint needs twice the size */
-+ if (bDbe) {
-+ szValue |= (1<<4);
-+ offset*=2;
-+ }
-+
-+ /* configure the FIFO */
-+ MGC_SelectEnd(pBase, pEnd->bEnd);
-+ switch ( bDir ) {
-+ case MUSB_EPD_D_TX:
-+ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 0x6);
-+ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 64 >> 3);
++ if ( status ) {
+
-+ pEnd->wMaxPacketSizeTx = wSize;
-+ pEnd->wMaxPacketSizeRx = 0;
-+ pEnd->bIsSharedFifo = FALSE;
-+ break;
-+ case MUSB_EPD_D_RX:
-+ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 0x6);
-+ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, (64 + 512 ) >> 3);
++ pUrb->status=status; /* */
+
-+ pEnd->wMaxPacketSizeTx = 0;
-+ pEnd->wMaxPacketSizeRx = wSize;
-+ pEnd->bIsSharedFifo = FALSE;
-+ break;
-+ case MUSB_EPD_D_INOUT:
-+ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, szValue);
-+ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, addValue);
++ if ( USB_ST_STALL!=status ) {
++ DBG(1, "Tx error on bEnd=%d, pUrb=%p, status=%d, proto=%s\n",
++ bEnd, pUrb, status, decode_urb_protocol(pUrb));
++ DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++ }
+
-+ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, szValue);
-+ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, addValue);
++ /* reset error bits */
++ wVal &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
++ MGC_M_TXCSR_H_NAKTIMEOUT);
++ wVal |= MGC_M_TXCSR_FRCDATATOG;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++ }
+
-+ pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=wSize;
-+ pEnd->bIsSharedFifo = TRUE;
-+ break;
++ } while (0);
+
-+ default:
-+ ERR("direction %d not supported\n", bDir);
-+ offset=0;
-+ break;
-+ }
+
-+ /* make sure the endmask is right */
-+ if ( offset ) {
-+ pThis->wEndMask |= (1 << pEnd->bEnd);
++ if ( !skip && pUrb->status==-EINPROGRESS ) {
++ mgc_linux_packet_tx(pThis, bEnd);
+ }
+
-+ /* TODO: flush the FIFO after an ep size change */
-+
++ /* complete the current request or start next tx transaction */
++ if ( pUrb->status!=-EINPROGRESS ) {
++ int toggle=(pUrb->status==USB_ST_STALL)
++ ? 0
++ : ((wVal & MGC_M_TXCSR_H_DATATOGGLE) ? 1 : 0);
++ pUrb->actual_length = pEnd->dwOffset;
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ complete_ep_urb(pThis, pEnd, pUrb, toggle);
++ } else {
++ spin_unlock(&pEnd->Lock);
++ if ( !skip ) {
+
-+ return offset;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++ MGC_M_TXCSR_TXPKTRDY);
++ }
++ DBG(1, "==>\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ }
+}
+
+/**
-+ * Configure the end points for DYNAMIC FIFO: array based End point
-+ * configuration.
-+ * @param pThis the controller
++ * Service an Rx-Ready interrupt for the given endpoint; see section 18.2.1
++ * of the manual for details.
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
+ */
-+void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
-+ uint8_t bEnd, bSkip;
-+ MGC_LinuxLocalEnd* pEnd;
-+ uint16_t wFifoOffset=0;
++void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++ struct urb* pUrb;
++ unsigned long flags;
++ uint16_t wRxCount, wRxCsrVal, wVal=0;
++ uint8_t bIsochError = FALSE;
++ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
+
-+ /* use the defined end points */
-+ pThis->bEndCount=MUSB_C_NUM_EPS;
++ DBG(2, "<== end%d\n", bEnd);
++ spin_lock(&pEnd->Lock);
++ DBG(3, "locked end%d, pUrb=%p\n", bEnd, MGC_GetCurrentUrb(pEnd));
+
-+#ifdef MUSB_PARANOID
-+ if ( MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_T_CNTRL
-+ && MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_AUTOCONFIG)
-+ {
-+ WARN("ep0 must be control with fixed size of %d\n",
-+ MGC_END0_FIFOSIZE);
++ pUrb = MGC_GetCurrentUrb(pEnd);
++ if ( !pUrb ) {
++ /* THIS SHOULD NEVER HAPPEN */
++ /* stop endpoint since we have no place for its data */
++ MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE;
++ spin_unlock(&pEnd->Lock);
++ DBG(1, "==> no RX URB on end %d!\n", bEnd);
++ return;
+ }
-+#endif
-+
-+ /* entry 0 is ep0, the default control endpoint */
-+ for (bEnd=0; bEnd<MUSB_C_NUM_EPS; bEnd++) {
-+ bSkip=0;
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
-+ pEnd->bIsSharedFifo = FALSE;
-+ pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=0;
-+
-+ switch ( MUSB_aEpFifoDescriptors[bEnd].bType ) {
-+ case MUSB_EPD_T_CNTRL:
-+ if ( bEnd ) {
-+ bSkip=1;
-+ WARN("Control ep when ep!=0 (ep%d); skipping\n", bEnd);
-+ }
-+ break;
-+
-+ case MUSB_EPD_T_ISOC: break;
-+
-+ case MUSB_EPD_T_BULK:
-+ switch ( MUSB_aEpFifoDescriptors[bEnd].bDir ) {
-+ case MUSB_EPD_D_TX: pThis->bBulkTxEnd = bEnd; break;
-+ case MUSB_EPD_D_RX: pThis->bBulkRxEnd = bEnd; break;
-+ case MUSB_EPD_D_INOUT:
-+ WARN("INOUTBULK: sharing ep%d\n", bEnd);
-+ break;
-+ default:
-+ bSkip=1;
-+ ERR("direction %d not supported for ep%d\n",
-+ MUSB_aEpFifoDescriptors[bEnd].bDir, bEnd);
-+ break;
-+ }
-+ break;
-+
-+ case MUSB_EPD_T_INTR: break;
-+ case MUSB_EPD_AUTOCONFIG: break;
-+
-+ default:
-+ bSkip=1;
-+ ERR("ep%d type %d not supported\n", bEnd,
-+ MUSB_aEpFifoDescriptors[bEnd].bType);
-+ break;
-+ }
-+
-+ if ( !MUSB_aEpFifoDescriptors[bEnd].wSize ) {
-+ continue; /* postpone to autoconfig */
-+ }
+
-+ if ( !bSkip ) {
-+ uint16_t offset=CONFIGURE_FIFO(pThis, &(pThis->aLocalEnd[bEnd]),
-+ &MUSB_aEpFifoDescriptors[bEnd], wFifoOffset );
-+ if ( offset ) {
-+ wFifoOffset += offset;
-+ }
-+ }
-+
++ if ( !pUrb->hcpriv ) {
++ DBG(1, "==> kickstarting it\n");
++ mgc_linux_kickstart_urb(pThis, bEnd);
++ spin_unlock(&pEnd->Lock);
++ return;
+ }
+
+#ifdef MUSB_PARANOID
-+ if ( wFifoOffset > 64 ) {
-+ ERR("Allocated %d bytes, more than the allowed %d\n",
-+ wFifoOffset, 64);
-+ } else {
-+ INFO("Allocated %d bytes, out of %d\n", wFifoOffset,
-+ 64);
-+ }
++ /* check URB */
++ if ( pUrb->hcpriv!=pEnd ) {
++ ERR("==> pUrb=%p on bEnd=%d (hcpriv=%p) is corrupt!\n", pUrb, bEnd, pUrb->hcpriv);
++ /* about the urb? */
++ spin_unlock(&pEnd->Lock);
++ return;
++ }
+#endif
+
-+}
-+
-+#else
-+/**
-+ * Configure the end points for DYNAMIC FIFO (old method).
-+ * @param pThis the controller
-+ */
-+void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
-+ uint8_t bEnd=1;
-+ MGC_LinuxLocalEnd* pEnd;
-+ void* pBase = pThis->pRegs;
-+ uint16_t wFifoOffset=MGC_END0_FIFOSIZE;
-+
-+ DBG(2, "<==\n");
++ if ( !MUSB_IS_HST(pThis) ) {
++ complete_ep_urb(pThis, pEnd, pUrb, 0);
++ return;
++ }
+
-+ /* use the defined end points */
-+ pThis->bEndCount=MUSB_C_NUM_EPS;
-+
-+ /* Dynamic FIFO sizing: use pre-computed values for EP0 */
-+ MGC_SelectEnd(pBase, 0);
-+ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 3);
-+ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 3);
-+ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 0);
-+ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, 0);
-+ pThis->wEndMask = 1;
-+
-+#if MGC_DFIFO_ISO_TX >= 0
++ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
+ MGC_SelectEnd(pBase, bEnd);
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
++ wVal = wRxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
++ wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
+
-+ /* reserve ISO Tx */
-+ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ISO_TX_VAL);
-+ pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_ISO_TX_VAL & 0xf)+3+(MGC_DFIFO_ISO_TX_VAL>>4));
-+ pEnd->wMaxPacketSizeRx = 0;
-+ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
-+ /* move to next */
-+ wFifoOffset += pEnd->wMaxPacketSizeTx;
-+ pEnd->bIsSharedFifo = FALSE;
-+ pThis->wEndMask |= (1 << bEnd);
-+ bEnd++;
-+#endif
++ DBG(3, "end %d wRxCsrVal=%04x, wRxCount=%d, pUrb->actual_length=%d\n", bEnd,
++ wRxCsrVal, wRxCount, pUrb->actual_length);
+
-+#if MGC_DFIFO_ISO_RX >= 0
-+ MGC_SelectEnd(pBase, bEnd);
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
++ do {
++ uint32_t status = 0;
+
-+ /* reserve ISO Rx */
-+ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ISO_RX_VAL);
-+ pEnd->wMaxPacketSizeTx = 0;
-+ pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_ISO_RX_VAL & 0xf)+3+(MGC_DFIFO_ISO_RX_VAL>>4));
-+ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
++ /* check for errors, concurrent stall & unlink is not really
++ * handled yet! */
++ if ( wRxCsrVal & MGC_M_RXCSR_H_RXSTALL ) {
++ pEnd->bStalled=TRUE;
++ DBG(1, "RX end %d STALL\n", bEnd);
++ status = USB_ST_STALL;
++ } else if(wRxCsrVal & MGC_M_RXCSR_H_ERROR) {
++ DBG(1, "end %d Rx error\n", bEnd);
++ DEBUG_CODE(1, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++ status=-ECONNRESET;
+
-+ /* move to next */
-+ wFifoOffset += pEnd->wMaxPacketSizeRx;
-+ pEnd->bIsSharedFifo = FALSE;
-+ pThis->wEndMask |= (1 << bEnd);
-+ bEnd++;
++ /* do the proper sequence to abort the transfer */
++ wVal &= ~MGC_M_RXCSR_H_REQPKT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0);
++
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwErrorRxPackets++;
+#endif
++ } else if(wRxCsrVal & MGC_M_RXCSR_DATAERROR) {
+
-+ MGC_SelectEnd(pBase, bEnd);
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
++ if (PIPE_BULK == pEnd->bTrafficType) {
++ /* cover it up if retries not exhausted, slow devices might
++ * not answer quickly enough: I was expecting a packet but the
++ * packet didn't come. The interrupt is generated after 3 failed
++ * attempts, it make MUSB_MAX_RETRIESx3 attempts total..
++ */
++ if ( pUrb->status==-EINPROGRESS &&
++ ++pEnd->bRetries < MUSB_MAX_RETRIES)
++ {
++ /* silently ignore it */
++ wRxCsrVal &= ~ MGC_M_RXCSR_DATAERROR;
++ wRxCsrVal &= ~MGC_M_RXCSR_RXPKTRDY;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++ wRxCsrVal | MGC_M_RXCSR_H_REQPKT);
+
-+ /* reserve bulk */
-+ pEnd->wMaxPacketSizeRx= 0;
-+ pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
-+ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_BLK_VAL);
-+ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
-+ pThis->bBulkTxEnd = bEnd;
-+ /* move to next */
-+ wFifoOffset += pEnd->wMaxPacketSizeTx;
-+ pThis->wEndMask |= (1 << bEnd);
-+ bEnd++;
++ MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
++ DBG(1, "rx error on ep%d, mgc_slow_device_kludge_delay=%d\n",
++ bEnd, mgc_slow_device_kludge_delay);
++ spin_unlock(&pEnd->Lock);
++ DBG(2, "==> cover rx error\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ return;
++ }
+
-+ MGC_SelectEnd(pBase, bEnd);
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
++ if ( pUrb->status==-EINPROGRESS ) {
++ DBG(-1, "urb=%p, protocol=%s timed out\n", pUrb,
++ decode_urb_protocol(pUrb));
++ status=-ECONNRESET;
++ }
+
-+ pEnd->wMaxPacketSizeTx= 0;
-+ pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
-+ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_BLK_VAL);
-+ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
-+ pThis->bBulkRxEnd = bEnd;
-+ /* move to next */
-+ wFifoOffset += pEnd->wMaxPacketSizeRx;
-+ pThis->wEndMask |= (1 << bEnd);
-+ bEnd++;
++ wVal &= ~MGC_M_RXCSR_H_REQPKT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0);
++ pEnd->bRetries=0;
+
-+ /* take care of the remaining eps */
-+ for(; bEnd < MUSB_C_NUM_EPS; bEnd++) {
-+ MGC_SelectEnd(pBase, bEnd);
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
-+
-+ MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ALL_VAL);
-+ MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ALL_VAL);
-+ pEnd->wMaxPacketSizeTx = pEnd->wMaxPacketSizeRx = 1 << (MGC_DFIFO_ALL_VAL+3);
-+ pEnd->bIsSharedFifo = TRUE;
-+ MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
-+ MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
-+
-+ wFifoOffset += pEnd->wMaxPacketSizeRx;
-+ pThis->wEndMask |= (1 << bEnd);
-+ }
++ /* do the proper sequence to abort the transfer;
++ * am I dealing with a slow device maybe? */
++ DBG(3, "end=%d device not responding\n", bEnd);
+
-+#ifdef MUSB_PARANOID
-+ if ( wFifoOffset > 64 ) {
-+ ERR("Allocated %d bytes, more than the allowed %d\n",
-+ wFifoOffset, 64);
-+ } else {
-+ INFO("Allocated %d bytes, out of %d\n",
-+ wFifoOffset, 64);
-+ }
-+#endif
-+
-+ DBG(2, "==>\n");
-+}
-+#endif
++ } else if(PIPE_ISOCHRONOUS == pEnd->bTrafficType) {
++ DBG(3, "bEnd=%d Isochronous error\n", bEnd);
++ bIsochError = TRUE;
++ }
+
-+#else
-+/**
-+ * Detect and configure the end points (no dynamic fifos).
-+ * @param pThis the controller
-+ */
-+void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
-+ uint8_t bEnd=0, reg;
-+ MGC_LinuxLocalEnd* pEnd;
-+ void* pBase = pThis->pRegs;
-+ /* how many of a given size/direction found: */
-+ uint8_t b2kTxEndCount = 0;
-+ uint8_t b2kRxEndCount = 0;
-+ uint8_t b1kTxEndCount = 0;
-+ uint8_t b1kRxEndCount = 0;
-+ /* the smallest 2k or 1k ends in Tx or Rx direction: */
-+ uint8_t b2kTxEnd = 0;
-+ uint8_t b2kRxEnd = 0;
-+ uint8_t b1kTxEnd = 0;
-+ uint8_t b1kRxEnd = 0;
-+ /* for tracking smallest: */
-+ uint16_t w2kTxSize = 0;
-+ uint16_t w1kTxSize = 0;
-+ uint16_t w2kRxSize = 0;
-+ uint16_t w1kRxSize = 0;
++#ifdef MUSB_CONFIG_PROC_FS
++ pEnd->dwErrorRxPackets++;
++#endif
++ }
+
-+ DBG(2, ">==\n");
++ /* an error won't process the data */
++ if ( status ) {
++ pUrb->status=status;
+
-+ for(bEnd = 1; bEnd < MUSB_C_NUM_EPS; bEnd++) {
-+ MGC_SelectEnd(pBase, bEnd);
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ pEnd->bEnd=bEnd;
++ /* data errors are signaled */
++ if ( USB_ST_STALL!=status ) {
++ DBG(3, "end %d Rx error, status=%d\n", bEnd, status);
++ DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++ } else {
++ mgc_hdrc_flush_fifo(pThis, bEnd, 1);
++ }
+
-+ /* read from core */
-+ reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_FIFOSIZE, bEnd);
-+ if(!reg) {
-+ /* 0's returned when no more endpoints */
-+ break;
++ DBG(3, "clearing all error bits, right away\n");
++ wVal &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_DATAERROR |
++ MGC_M_RXCSR_H_RXSTALL );
++ wVal &= ~MGC_M_RXCSR_RXPKTRDY;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
+ }
-+
-+ pEnd->wMaxPacketSizeTx = 1 << (reg & 0x0f);
-+ /* shared TX/RX FIFO? */
-+ if((reg & 0xf0) == 0xf0) {
-+ pEnd->wMaxPacketSizeRx = 1 << (reg & 0x0f);
-+ pEnd->bIsSharedFifo = TRUE;
++
++ } while (0);
++
++ /* no errors, unload... */
++ if ( pUrb->status==-EINPROGRESS ) {
++
++ /* be sure a packet is ready for unloading */
++ if( !wRxCsrVal & MGC_M_RXCSR_RXPKTRDY ) {
++ pUrb->status = USB_ST_INTERNALERROR;
++ /* do the proper sequence to abort the transfer */
++ wVal &= ~MGC_M_RXCSR_H_REQPKT;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++ DBG(3, "Rx interrupt with no errors or packet!\n");
+ } else {
-+ pEnd->wMaxPacketSizeRx = 1 << ((reg & 0xf0) >> 4);
-+ pEnd->bIsSharedFifo = FALSE;
-+ }
-+
-+ /* track certain sizes to try to reserve a bulk resource */
-+ if(pEnd->wMaxPacketSizeTx >= 2048) {
-+ b2kTxEndCount++;
-+ if(!b2kTxEnd || (pEnd->wMaxPacketSizeTx < w2kTxSize)) {
-+ b2kTxEnd = bEnd;
-+ w2kTxSize = pEnd->wMaxPacketSizeTx;
-+ }
-+ }
-+
-+ if(pEnd->wMaxPacketSizeRx >= 2048) {
-+ b2kRxEndCount++;
-+ if(!b2kRxEnd || (pEnd->wMaxPacketSizeRx < w2kRxSize)) {
-+ b2kRxEnd = bEnd;
-+ w2kRxSize = pEnd->wMaxPacketSizeRx;
-+ }
-+ }
-+
-+ if(pEnd->wMaxPacketSizeTx >= 1024) {
-+ b1kTxEndCount++;
-+ if(!b1kTxEnd || (pEnd->wMaxPacketSizeTx < w1kTxSize)) {
-+ b1kTxEnd = bEnd;
-+ w1kTxSize = pEnd->wMaxPacketSizeTx;
++ /* we are expecting traffic */
++#ifdef MUSB_DMA
++ if(pEnd->pDmaChannel) {
++ if(MGC_DMA_STATUS_FREE==
++ pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel))
++ {
++ pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
++ }
+ }
++#endif
++ mgc_linux_packet_rx(pThis, bEnd, wRxCount, bIsochError);
+ }
-+
-+ if(pEnd->wMaxPacketSizeRx >= 1024) {
-+ b1kRxEndCount++;
-+ if(!b1kRxEnd || (pEnd->wMaxPacketSizeRx < w1kTxSize)) {
-+ b1kRxEnd = bEnd;
-+ w1kRxSize = pEnd->wMaxPacketSizeRx;
-+ }
-+ }
-+
-+ pThis->bEndCount++;
-+ pThis->wEndMask |= (1 << bEnd);
-+ } /* init queues etc. etc. etc. */
-+
-+ /* if possible, reserve the smallest 2k-capable Tx end for bulk */
-+ if(b2kTxEnd && (b2kTxEndCount > 1)) {
-+ pThis->bBulkTxEnd = b2kTxEnd;
-+ INFO("Reserved end %d for bulk double-buffered Tx\n", b2kTxEnd);
-+ }
-+ /* ...or try 1k */
-+ else if(b1kTxEnd && (b1kTxEndCount > 1)) {
-+ pThis->bBulkTxEnd = b1kTxEnd;
-+ INFO("Reserved end %d for bulk Tx\n", b1kTxEnd);
+ }
+
-+ /* if possible, reserve the smallest 2k-capable Rx end for bulk */
-+ if(b2kRxEnd && (b2kRxEndCount > 1)) {
-+ pThis->bBulkRxEnd = b2kRxEnd;
-+ INFO("Reserved end %d for bulk double-buffered Rx\n", b2kRxEnd);
-+ }
-+ /* ...or try 1k */
-+ else if(b1kRxEnd && (b1kRxEndCount > 1)) {
-+ pThis->bBulkRxEnd = b1kRxEnd;
-+ INFO("Reserved end %d for bulk Rx\n", b1kRxEnd);
++ /* complete the current request or start next one clearing RxPktRdy
++ * and setting ReqPkt */
++ if ( pUrb->status!=-EINPROGRESS ) {
++ int toggle=(pUrb->status==USB_ST_STALL)
++ ? 0
++ : ((wVal & MGC_M_RXCSR_H_DATATOGGLE) ? 1 : 0);
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++ complete_ep_urb(pThis, pEnd, pUrb, toggle);
++ DBG(2, "==>\n");
++ } else {
++ spin_unlock(&pEnd->Lock);
++ wVal |= MGC_M_RXCSR_H_REQPKT;
++ wVal &= ~MGC_M_RXCSR_RXPKTRDY;
++ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++ DBG(2, "==>\n");
++ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
+ }
-+
-+ DBG(2, "<==\n");
+}
-+#endif
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_hcd.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_hcd.c
---- linux-2.6.20/drivers/usb/nomadik/musb_hcd.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_hcd.c 2008-09-17 13:23:33.000000000 +0530
-@@ -0,0 +1,869 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_hcd.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
++/* *************************************************************************
+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
++ **************************************************************************/
++
++/**
++ * Find a local endpoint suitable for transmitting the given urb minimizing
++ * the reconfigurations. The best localendpoint is selceted using the following
++ * criterion:
++ * - ep0 is used for control Urbs
++ * - for bulk Urbs only (when available) choose the Tx or Rx reserved end
++ * - determine direction, size and traffic type
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * @param pThis instance pointer
++ * @param pURB URB pointer
++ * @return suitable local endpoint
++ * @return -1 if nothing appropriate
+ */
++int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb)
++{
++ MGC_LinuxLocalEnd* pEnd;
++ int32_t dwDiff;
++ uint16_t wBestDiff = 0xffff;
++ uint16_t wBestExactDiff = 0xffff;
++ uint8_t bDirOk, bTrafficOk, bSizeOk, bExact;
++ int nEnd=-1, nBestEnd = -1, nBestExactEnd = -1;
++ unsigned int nOut = usb_pipeout( pUrb->pipe );
++ uint16_t wPacketSize = usb_maxpacket(pUrb->dev, pUrb->pipe, nOut);
++ uint8_t bRemoteEnd = usb_pipeendpoint(pUrb->pipe);
++ uint8_t bIsBulk = usb_pipebulk(pUrb->pipe);
++ uint8_t bRemoteAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
+
-+#include <asm/arch/pexp.h>
-+static void mgc_hcd_stop(struct usb_hcd *hcd);
-+static int __devinit mgc_hcd_start(struct usb_hcd *hcd);
-+static int mgc_hcd_submit_urb(struct usb_hcd *hcd,struct usb_host_endpoint *ep,
-+ struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
-+static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb);
-+static int mgc_hcd_get_frame_number(struct usb_hcd *hcd);
-+static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd);
-+static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd,
-+ struct usb_host_endpoint *ep);
-+static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
++ DBG(2, "<== pUrb=%p\n", pUrb);
+
-+static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
-+ u16 wIndex, char *pData, u16 wLength);
-+static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData);
-+int Urb_status=0;
-+/* ------------------------------------------------------- */
-+static int mgc_bus_resume(struct usb_hcd *phcd)
-+{
-+ MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
-+ char* pBase = (char*)pThis->pRegs;
++ /* control is always EP0, and can always be queued */
++ if ( usb_pipecontrol(pUrb->pipe) ) {
++ DBG(2, "==> is a control pipe use ep0\n");
++ return 0;
++ }
+
-+ nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
-+ /* Reinitialize the interrupt*/
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, 0x20);
-+ MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0xFFFF);
-+ MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0xFFFE);
-+ MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xF7);
-+ MGC_Write8(pBase, MGC_O_HDRC_INDEX ,0x00);
-+
-+ /* Configure the endpoints*/
-+ MGC_HdrcConfigureEps(pThis);
-+ MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);
-+ mod_timer(¬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
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+#ifndef __MUSB_HDRC_DEFS_H__
-+#define __MUSB_HDRC_DEFS_H__
++#ifndef _MUSB_HOST_H
++#define _MUSB_HOST_H
+
-+/*
-+ * HDRC-specific definitions
-+ * $Revision: 1.8 $
-+ */
++extern int mgc_slow_device_kludge_delay;
+
-+#define MGC_MAX_USB_ENDS 16
++#define SPIN_LOCK_IRQSAVE(l, f) do { spin_lock_irqsave(l, f); if ( mgc_slow_device_kludge_delay) { udelay(mgc_slow_device_kludge_delay*2); } DBG(3, "IRQ DISABLED\n"); } while (0)
++#define SPIN_UNLOCK_IRQRESTORE(l,f) do { DBG(3, "IRQ ENABLED\n"); spin_unlock_irqrestore(l, f); } while (0)
+
-+#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */
++struct urb;
+
-+/*
-+ * MUSBMHDRC Register map
-+ */
++int mgc_init_root_hub(MGC_LinuxCd *pThis);
++int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd);
++MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb);
+
-+/* Common USB registers */
++int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
++int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd,
++ struct urb* pUrb);
+
-+#define MGC_O_HDRC_FADDR 0x00 /* 8-bit */
-+#define MGC_O_HDRC_POWER 0x01 /* 8-bit */
++static inline int mgc_urb_is_periodic(struct urb *pUrb) {
++ return (usb_pipeint(pUrb->pipe) || usb_pipeisoc(pUrb->pipe));
++}
+
-+#define MGC_O_HDRC_INTRTX 0x02 /* 16-bit */
-+#define MGC_O_HDRC_INTRRX 0x04
-+#define MGC_O_HDRC_INTRTXE 0x06
-+#define MGC_O_HDRC_INTRRXE 0x08
-+#define MGC_O_HDRC_INTRUSB 0x0A /* 8 bit */
-+#define MGC_O_HDRC_INTRUSBE 0x0B /* 8 bit */
-+#define MGC_O_HDRC_FRAME 0x0C
-+#define MGC_O_HDRC_INDEX 0x0E /* 8 bit */
-+#define MGC_O_HDRC_TESTMODE 0x0F /* 8 bit */
++extern char* decode_urb_protocol(struct urb* pUrb);
+
-+/* Get offset for a given FIFO */
-+#define MGC_FIFO_OFFSET(_bEnd) (0x20 + (_bEnd * 4))
+
-+/* Additional Control Registers */
++#ifdef MUSB_USE_HCD_DRIVER
++int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis);
++#endif
+
-+#define MGC_O_HDRC_DEVCTL 0x60 /* 8 bit */
++#ifdef MUSB_HOST
++extern int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb);
++extern int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
+
-+/* These are actually indexed: */
-+#define MGC_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */
-+#define MGC_O_HDRC_RXFIFOSZ 0x63 /* 8-bit (see masks) */
-+#define MGC_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */
-+#define MGC_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */
++#ifdef MUSB_V26
++extern int MGC_LinuxSubmitUrb26(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
++extern int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status);
++#endif
+
-+#define MGC_O_HDRC_TOPCONTROL 0x204 /* top control register 16-bit */
++#ifdef MUSB_V24
++extern int MGC_LinuxSubmitUrb24(struct urb* pUrb);
++extern int MGC_LinuxUnlinkUrb24(struct urb* pUrb);
++#endif
+
-+/* offsets to registers in flat model */
-+#define MGC_O_HDRC_TXMAXP 0x00
-+#define MGC_O_HDRC_TXCSR 0x02
-+#define MGC_O_HDRC_CSR0 MGC_O_HDRC_TXCSR /* re-used for EP0 */
-+#define MGC_O_HDRC_RXMAXP 0x04
-+#define MGC_O_HDRC_RXCSR 0x06
-+#define MGC_O_HDRC_RXCOUNT 0x08
-+#define MGC_O_HDRC_COUNT0 MGC_O_HDRC_RXCOUNT /* re-used for EP0 */
-+#define MGC_O_HDRC_TXTYPE 0x0A
-+#define MGC_O_HDRC_TYPE0 MGC_O_HDRC_TXTYPE /* re-used for EP0 */
-+#define MGC_O_HDRC_TXINTERVAL 0x0B
-+#define MGC_O_HDRC_NAKLIMIT0 MGC_O_HDRC_TXINTERVAL /* re-used for EP0 */
-+#define MGC_O_HDRC_RXTYPE 0x0C
-+#define MGC_O_HDRC_RXINTERVAL 0x0D
-+#define MGC_O_HDRC_FIFOSIZE 0x0F
-+#define MGC_O_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */
++extern void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis);
+
-+#define MGC_END_OFFSET(_bEnd, _bOffset) (0x100 + (0x10*_bEnd) + _bOffset)
+
-+/* "bus control" registers */
-+#define MGC_O_HDRC_TXFUNCADDR 0x00
-+#define MGC_O_HDRC_TXHUBADDR 0x02
-+#define MGC_O_HDRC_TXHUBPORT 0x03
++#else /* host not defined */
+
-+#define MGC_O_HDRC_RXFUNCADDR 0x04
-+#define MGC_O_HDRC_RXHUBADDR 0x06
-+#define MGC_O_HDRC_RXHUBPORT 0x07
++#ifdef MUSB_V26_POST10
++extern int MGC_LinuxHubSuspend(struct usb_bus *pBus);
++extern int MGC_LinuxHubResume(struct usb_bus *pBus);
++#endif
+
-+#define MGC_BUSCTL_OFFSET(_bEnd, _bOffset) (0x80 + (8*_bEnd) + _bOffset)
++inline void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd) {
++ DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd) {
++ DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd) {
++ DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) {
++ DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis) {
++ DBG(3, "#HOST DISABLED\n");
++}
++#endif
+
++
++#endif /* _MUSB_HOST_H */
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c
+@@ -0,0 +1,321 @@
+/*
-+ * MUSBHDRC Register bit masks
++ * linux/drivers/usb/nomadik/musb_ioctl.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+/* POWER */
++#include <asm/uaccess.h>
++#include <linux/kernel.h>
+
-+#define MGC_M_POWER_ISOUPDATE 0x80
-+#define MGC_M_POWER_SOFTCONN 0x40
-+#define MGC_M_POWER_HSENAB 0x20
-+#define MGC_M_POWER_HSMODE 0x10
-+#define MGC_M_POWER_RESET 0x08
-+#define MGC_M_POWER_RESUME 0x04
-+#define MGC_M_POWER_SUSPENDM 0x02
-+#define MGC_M_POWER_ENSUSPEND 0x01
++#include <linux/usb.h>
++
++#include "musbdefs.h"
++#include "musb_host.h"
++
++#ifdef MUSB_DEBUG
++extern int mgc_slow_device_kludge_delay;
++#endif
++
++/**
++ * Zap the driver (warm start)
++ * @param pThis the controller
++ */
++void MGC_Zap(MGC_LinuxCd* pThis) {
++
++#ifdef MUSB_PARANOID
++ if ( !pThis ) {
++ ERR("Controller not initialized\n");
++ return;
++ }
++#endif
++
++ MGC_HdrcStop(pThis);
++
++#ifdef MUSB_VIRTHUB
++ MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
++ pThis->pRootDevice = NULL;
++ mgc_hcd_flush(pThis);
++#endif
+
-+/* INTRUSB */
-+#define MGC_M_INTR_SUSPEND 0x01
-+#define MGC_M_INTR_RESUME 0x02
-+#define MGC_M_INTR_RESET 0x04
-+#define MGC_M_INTR_BABBLE 0x04
-+#define MGC_M_INTR_SOF 0x08
-+#define MGC_M_INTR_CONNECT 0x10
-+#define MGC_M_INTR_DISCONNECT 0x20
-+#define MGC_M_INTR_SESSREQ 0x40
-+#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */
-+#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
++ WARN("Controller Stopped\n");
+
-+/* DEVCTL */
-+#define MGC_M_DEVCTL_BDEVICE 0x80
-+#define MGC_M_DEVCTL_FSDEV 0x40
-+#define MGC_M_DEVCTL_LSDEV 0x20
-+#define MGC_M_DEVCTL_VBUS 0x18
-+#define MGC_S_DEVCTL_VBUS 3
-+#define MGC_M_DEVCTL_HM 0x04
-+#define MGC_M_DEVCTL_HR 0x02
-+#define MGC_M_DEVCTL_SESSION 0x01
+
-+/* TESTMODE */
++#ifdef MUSB_HOST
++ MGC_InitLocalEndPoints(pThis);
++#endif
+
-+#define MGC_M_TEST_FORCE_HOST 0x80
-+#define MGC_M_TEST_FIFO_ACCESS 0x40
-+#define MGC_M_TEST_FORCE_FS 0x20
-+#define MGC_M_TEST_FORCE_HS 0x10
-+#define MGC_M_TEST_PACKET 0x08
-+#define MGC_M_TEST_K 0x04
-+#define MGC_M_TEST_J 0x02
-+#define MGC_M_TEST_SE0_NAK 0x01
++#ifdef MUSB_GADGET
+
-+/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
-+#define MGC_M_FIFOSZ_DPB 0x10
-+/* allocation size (8, 16, 32, ... 4096) */
-+#define MGC_M_FIFOSZ_SIZE 0x0f
++#endif
+
-+/* CSR0 */
-+#define MGC_M_CSR0_FLUSHFIFO 0x0100
-+#define MGC_M_CSR0_TXPKTRDY 0x0002
-+#define MGC_M_CSR0_RXPKTRDY 0x0001
++ WAIT_MS(1000);
++ MGC_HdrcStart( pThis );
++ WARN("Controller Restarted\n");
++}
+
-+/* CSR0 in Peripheral mode */
-+#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
-+#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
-+#define MGC_M_CSR0_P_SENDSTALL 0x0020
-+#define MGC_M_CSR0_P_SETUPEND 0x0010
-+#define MGC_M_CSR0_P_DATAEND 0x0008
-+#define MGC_M_CSR0_P_SENTSTALL 0x0004
++/**
++ * Start a session. Depeing on the controller mode (cable end) it will
++ * pwer VBUS/initiate SRP and/or it will behave like a gadget.
++ * @param pThis the controller
++ *
++ */
++void MGC_Session(MGC_LinuxCd* pThis) {
++ uint8_t bReg, sesn=0;
+
-+/* CSR0 in Host mode */
-+#define MGC_M_CSR0_H_NO_PING 0x0800
-+#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */
-+#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */
-+#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080
-+#define MGC_M_CSR0_H_STATUSPKT 0x0040
-+#define MGC_M_CSR0_H_REQPKT 0x0020
-+#define MGC_M_CSR0_H_ERROR 0x0010
-+#define MGC_M_CSR0_H_SETUPPKT 0x0008
-+#define MGC_M_CSR0_H_RXSTALL 0x0004
++#ifdef MUSB_PARANOID
++ if ( !pThis ) {
++ ERR("Controller not initialized\n");
++ return;
++ }
++#endif
+
-+/* TxType/RxType */
-+#define MGC_M_TYPE_SPEED 0xc0
-+#define MGC_S_TYPE_SPEED 6
-+#define MGC_TYPE_SPEED_HIGH 1
-+#define MGC_TYPE_SPEED_FULL 2
-+#define MGC_TYPE_SPEED_LOW 3
-+#define MGC_M_TYPE_PROTO 0x30
-+#define MGC_S_TYPE_PROTO 4
-+#define MGC_M_TYPE_REMOTE_END 0xf
++ if ( MUSB_IS_ERR(pThis) ) {
++ WARN("Error mode, zap the driver first\n");
++ }
+
-+/* CONFIGDATA */
+
-+#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */
-+#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */
-+#define MGC_M_CONFIGDATA_BIGENDIAN 0x20
-+#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */
-+#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */
-+#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */
-+#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */
-+#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* data width 0 => 8bits, 1 => 16bits */
++ if ( sesn ) {
++ ERR("A %s session is active; terminate it first\n",
++ MUSB_MODE(pThis));
++ return;
++ }
+
-+/* TXCSR in Peripheral and Host mode */
+
-+#define MGC_M_TXCSR_AUTOSET 0x8000
-+#define MGC_M_TXCSR_ISO 0x4000
-+#define MGC_M_TXCSR_MODE 0x2000
-+#define MGC_M_TXCSR_DMAENAB 0x1000
-+#define MGC_M_TXCSR_FRCDATATOG 0x0800
-+#define MGC_M_TXCSR_DMAMODE 0x0400
-+#define MGC_M_TXCSR_CLRDATATOG 0x0040
-+#define MGC_M_TXCSR_FLUSHFIFO 0x0008
-+#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
-+#define MGC_M_TXCSR_TXPKTRDY 0x0001
++ /* WHY!?!?! this looks like a race condition to me */
++ bReg = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL);
++ MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, bReg | MGC_M_DEVCTL_SESSION);
++}
+
-+/* TXCSR in Peripheral mode */
+
-+#define MGC_M_TXCSR_P_INCOMPTX 0x0080
-+#define MGC_M_TXCSR_P_SENTSTALL 0x0020
-+#define MGC_M_TXCSR_P_SENDSTALL 0x0010
-+#define MGC_M_TXCSR_P_UNDERRUN 0x0004
++/**
++ * Change the debug level.
++ * @param level the new level
++ */
++void MGC_SetDebugLevel(int level) {
++#if MUSB_DEBUG > 0
++ MGC_DebugLevel=level;
++ INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel);
++#endif
++}
+
-+/* TXCSR in Host mode */
++/**
++ * Change the slow device delay.
++ * @param delay the new delay
++ */
++int MGC_SetDeviceDelay(int delay) {
++ if ( delay>0 ) {
++ mgc_slow_device_kludge_delay=delay;
++ }
++ return mgc_slow_device_kludge_delay;
++}
+
-+#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200
-+#define MGC_M_TXCSR_H_DATATOGGLE 0x0100
-+#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080
-+#define MGC_M_TXCSR_H_RXSTALL 0x0020
-+#define MGC_M_TXCSR_H_ERROR 0x0004
++/** Dump the current status and compile options.
++ * @param pThis the device driver instance
++ * @param buffer where to dump the status; it must be big enough hold the
++ * result otherwise "BAD THINGS HAPPENS(TM)".
++ */
++int dump_header_stats(MGC_LinuxCd* pThis, char *buffer) {
++ int code, count=0;
++ const uint8_t* pBase=pThis->pRegs;
+
-+/* RXCSR in Peripheral and Host mode */
++ *buffer=0;
+
-+#define MGC_M_RXCSR_AUTOCLEAR 0x8000
-+#define MGC_M_RXCSR_DMAENAB 0x2000
-+#define MGC_M_RXCSR_DISNYET 0x1000
-+#define MGC_M_RXCSR_DMAMODE 0x0800
-+#define MGC_M_RXCSR_INCOMPRX 0x0100
-+#define MGC_M_RXCSR_CLRDATATOG 0x0080
-+#define MGC_M_RXCSR_FLUSHFIFO 0x0010
-+#define MGC_M_RXCSR_DATAERROR 0x0008
-+#define MGC_M_RXCSR_FIFOFULL 0x0002
-+#define MGC_M_RXCSR_RXPKTRDY 0x0001
++ code=sprintf(&buffer[count],
++ "Compile Options: [debug=%d][dma=%s][gadget=%s][otg=%s][eps=%d]\n",
++#if MUSB_DEBUG>0
++ MGC_DebugLevel
++#else
++ -1
++#endif
++ ,
++#ifdef MUSB_DMA
++ "yes"
++#else
++ "no"
++#endif
++ ,
++#ifdef MUSB_GADGET
++ "yes"
++#else
++ "no"
++#endif
++ ,
++#ifdef MUSB_OTG
++ "yes"
++#else
++ "no"
++#endif
++ ,pThis->bEndCount);
++ if ( code<0 ) {
++ ERR("A problem generating the report\n");
++ return count;
++ } else {
++ count+=code;
++ }
+
-+/* RXCSR in Peripheral mode */
++ code=sprintf(&buffer[count],
++ "Current Status: %sDRC, Mode=%s (%s=%d) (Power=%02x, DevCtl=%02x)\n",
++ ( pThis->bIsMultipoint ? "MH" : "H"),
++ MUSB_MODE(pThis),
++#ifdef MUSB_GADGET
++ "address",
++ (MUSB_IS_DEV(pThis)?pThis->bAddress:0,
++#else
++ "delay",
++ mgc_slow_device_kludge_delay,
++#endif
++ MGC_Read8(pBase, MGC_O_HDRC_POWER),
++ MGC_Read8(pBase, MGC_O_HDRC_DEVCTL));
++ if ( code<0 ) {
++ ERR("A problem generating the report\n");
++ return count;
++ } else {
++ count+=code;
++ }
+
-+#define MGC_M_RXCSR_P_ISO 0x4000
-+#define MGC_M_RXCSR_P_SENTSTALL 0x0040
-+#define MGC_M_RXCSR_P_SENDSTALL 0x0020
-+#define MGC_M_RXCSR_P_OVERRUN 0x0004
++#ifdef MUSB_USE_HCD_DRIVER
++ {
++ int i=0;
++ mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
+
-+/* RXCSR in Host mode */
++ code=sprintf(&buffer[count],
++ "HCD: urb_queue_count=%d urb_exec_count=%d\n",
++ pQueue->urb_queue_count, pQueue->urb_exec_count);
++ if ( code<0 ) {
++ ERR("A problem generating the report\n");
++ return count;
++ } else {
++ count+=code;
++ }
+
-+#define MGC_M_RXCSR_H_AUTOREQ 0x4000
-+#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400
-+#define MGC_M_RXCSR_H_DATATOGGLE 0x0200
-+#define MGC_M_RXCSR_H_RXSTALL 0x0040
-+#define MGC_M_RXCSR_H_REQPKT 0x0020
-+#define MGC_M_RXCSR_H_ERROR 0x0004
++ for (i=0; i<pThis->bEndCount; i++) {
++ if ( !mgc_ep_is_idle( &pThis->aLocalEnd[i] ) ) {
++ code=sprintf(&buffer[count], "ep%d, current=%p\n",
++ i, MGC_GetCurrentUrb(&pThis->aLocalEnd[i]));
++ if ( code<0 ) {
++ ERR("A problem generating the report\n");
++ return count;
++ } else {
++ count+=code;
++ }
++ }
++ }
++ }
++#endif
+
-+/* HUBADDR */
-+#define MGC_M_HUBADDR_MULTI_TT 0x80
++ return count;
++}
+
+
-+/* TXCSR in Peripheral and Host mode */
++/**
++ * decode (convert to a name) the protocol used on an endpoint.
++ * @param pThis the controller
++ * @param bEnd the endpoint
++ */
++static char* decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
++ char* pProto = "Err ";
+
-+#define MGC_M_TXCSR2_AUTOSET 0x80
-+#define MGC_M_TXCSR2_ISO 0x40
-+#define MGC_M_TXCSR2_MODE 0x20
-+#define MGC_M_TXCSR2_DMAENAB 0x10
-+#define MGC_M_TXCSR2_FRCDATATOG 0x08
-+#define MGC_M_TXCSR2_DMAMODE 0x04
++ if ( MUSB_IS_DEV(pThis) ) {
++#ifdef MUSB_GAGDET
++ pProto=decode_dev_ep_protocol(pThis, bEnd);
++#endif
++ } else if ( MUSB_IS_HST(pThis) ) {
++#ifdef MUSB_HOST
++ pProto=decode_hst_ep_protocol(pThis, bEnd);
++#endif
++ }
+
-+#define MGC_M_TXCSR1_CLRDATATOG 0x40
-+#define MGC_M_TXCSR1_FLUSHFIFO 0x08
-+#define MGC_M_TXCSR1_FIFONOTEMPTY 0x02
-+#define MGC_M_TXCSR1_TXPKTRDY 0x01
++ return pProto;
++}
+
-+/* TXCSR in Peripheral mode */
++#ifdef MUSB_HOST
+
-+#define MGC_M_TXCSR1_P_INCOMPTX 0x80
-+#define MGC_M_TXCSR1_P_SENTSTALL 0x20
-+#define MGC_M_TXCSR1_P_SENDSTALL 0x10
-+#define MGC_M_TXCSR1_P_UNDERRUN 0x04
++/**
++ * Dump statistics for a local end (driver operaiting in host mode).
++ * @param pThis the device driver instance
++ * @param bEnd
++ * @param aBuffer the buffer to print the report to
++ */
++int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer) {
++ int code, count=0;
++ MGC_LinuxLocalEnd* pEnd=&pThis->aLocalEnd[bEnd];
+
-+/* TXCSR in Host mode */
++ spin_lock(&pEnd->Lock);
+
-+#define MGC_M_TXCSR1_H_NAKTIMEOUT 0x80
-+#define MGC_M_TXCSR1_H_RXSTALL 0x20
-+#define MGC_M_TXCSR1_H_ERROR 0x04
++ do {
+
-+/* RXCSR in Peripheral and Host mode */
++ if ( mgc_ep_is_idle(pEnd) ) {
++ code=snprintf(aBuffer, 256-count,
++ "End-%01x: Idle (%s, proto=%s, pktsize=%04x, address=%02x, end=%02x\n",
++ bEnd, ( pEnd->bIsTx ? "Tx" : "Rx" ), decode_protocol(pThis, bEnd),
++ pEnd->wPacketSize, pEnd->bRemoteAddress, pEnd->bRemoteEnd);
++ } else {
++ code=snprintf(aBuffer, 256-count,
++ "End-%01x: %s (urb=%p), %s, proto=%s, pkt size=%04x, address=%02x, end=%02x\n",
++ bEnd, "Busy", MGC_GetCurrentUrb(pEnd),
++ ( pEnd->bIsTx ? "Tx" : "Rx" ),
++ decode_protocol(pThis, bEnd),
++ pEnd->wPacketSize,
++ pEnd->bRemoteAddress,
++ pEnd->bRemoteEnd);
++ }
+
-+#define MGC_M_RXCSR2_AUTOCLEAR 0x80
-+#define MGC_M_RXCSR2_DMAENAB 0x20
-+#define MGC_M_RXCSR2_DISNYET 0x10
-+#define MGC_M_RXCSR2_DMAMODE 0x08
-+#define MGC_M_RXCSR2_INCOMPRX 0x01
++ if ( code<0 ) {
++ break;
++ } else {
++ count+=code;
++ }
+
-+#define MGC_M_RXCSR1_CLRDATATOG 0x80
-+#define MGC_M_RXCSR1_FLUSHFIFO 0x10
-+#define MGC_M_RXCSR1_DATAERROR 0x08
-+#define MGC_M_RXCSR1_FIFOFULL 0x02
-+#define MGC_M_RXCSR1_RXPKTRDY 0x01
++ if ( MUSB_IS_HST(pThis) ) {
++ code = snprintf(&aBuffer[count], 256-count,
++ " %10ld bytes Rx in %10ld pkts; %10ld errs, %10ld overruns\n",
++ pEnd->dwTotalRxBytes,
++ pEnd->dwTotalRxPackets,
++ pEnd->dwErrorRxPackets,
++ pEnd->dwMissedRxPackets);
++ if ( code<0 ) {
++ break;
++ } else {
++ count+=code;
++ }
+
-+/* RXCSR in Peripheral mode */
++ code=snprintf(&aBuffer[count], 256-count,
++ " %10ld bytes Tx in %10ld pkts; %10ld errs, %10ld underruns\n",
++ pEnd->dwTotalTxBytes,
++ pEnd->dwTotalTxPackets,
++ pEnd->dwErrorTxPackets,
++ pEnd->dwMissedTxPackets);
++ if ( code<0 ) {
++ break;
++ } else {
++ count+=code;
++ }
++ } else {
++ /* no stats for gadget, yet! */
++ }
++ } while(0);
+
-+#define MGC_M_RXCSR2_P_ISO 0x40
-+#define MGC_M_RXCSR1_P_SENTSTALL 0x40
-+#define MGC_M_RXCSR1_P_SENDSTALL 0x20
-+#define MGC_M_RXCSR1_P_OVERRUN 0x04
++ spin_unlock(&pEnd->Lock);
++ if ( code<0 ) {
++ ERR("An error generating the report");
++ return code;
++ }
+
-+/* RXCSR in Host mode */
++ return count;
++}
++#endif
+
-+#define MGC_M_RXCSR2_H_AUTOREQ 0x40
-+#define MGC_M_RXCSR1_H_RXSTALL 0x40
-+#define MGC_M_RXCSR1_H_REQPKT 0x20
-+#define MGC_M_RXCSR1_H_ERROR 0x04
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h
+@@ -0,0 +1,32 @@
++/*
++ * linux/drivers/usb/nomadik/musb_ioctl.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
+
-+/* Top control register */
-+#define MGC_M_TOPCTRL_MODE_ULPI 0x09
-+#define MGC_M_TOPCTRL_MODE_SRST 0x04
++#include "musbdefs.h"
+
-+#endif /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.c
---- linux-2.6.20/drivers/usb/nomadik/musb_host.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.c 2008-08-08 19:15:25.000000000 +0530
-@@ -0,0 +1,2791 @@
++void MGC_Zap(MGC_LinuxCd* pThis);
++void MGC_Session(MGC_LinuxCd* pThis);
++void MGC_SetDebugLevel(int level);
++int MGC_SetDeviceDelay(int delay);
++int dump_header_stats(MGC_LinuxCd* pThis, char *buffer);
++char*decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
++#ifdef MUSB_HOST
++int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
++#endif
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c
+@@ -0,0 +1,2306 @@
+/*
-+ * linux/drivers/usb/nomadik/musb_host.c
++ * linux/drivers/usb/nomadik/musb_plat_uds.c
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++/*
++ * Introduction.
++ * The ICD works like the other Linux HCDs/Gadgets: it is threadless,
++ * so it does everything either in response to an interrupt,
++ * or during a call from an upper layer.
++ * It implements a virtual root hub, so as to make uniform use
++ * of the Linux hub driver.Linux
++
++ *
++ * The Linux (host-side) USB core has no concept of binding (the authors
++ * apparently missed the point of the pipe discussion in the USB spec).
++ * Instead, class drivers simply submit URBs, and an HCD may reject
++ * or defer them if sufficient resources are not available.
++ * This means class drivers have no way to know if their requirements
++ * can possibly be fulfilled, and may be blocked indefinitely by others,
++ * without the end-user knowing why.
++ * Therefore, whether things will work depends on the order of URB submissions
++ * (which is dictated by the order of device insertion and/or driver loading
++ * and thread scheduling).
++ *
++ * The URB encodes pipe information in an integer,
++ * requiring table searches (hurting performance).
++ *
++ * For the HDRC, local endpoint 0 is the only choice for control traffic,
++ * so it is reprogrammed as needed, and locked during transfers.
++ * Bulk transfers are queued to the available local endpoint with
++ * the smallest possible FIFO in the given direction
++ * that will accomodate the transactions.
++ *
++ * A typical response to the completion of a periodic URB is immediate
++ * submission of another one, so the HCD does not assume it can reprogram
++ * a local periodic-targetted endpoint for another purpose.
++ * Instead, submission of a periodic URB is taken as a permanent situation,
++ * so that endpoint is untouched.
++ * One could imagine reprogramming periodic endpoints for other uses
++ * between their polling intervals, effectively interleaving traffic on them.
++ * Unfortunately, this assumes no device would ever NAK periodic tokens.
++ * This is because the core no notification to software when an attempted
++ * periodic transaction is NAKed (its NAKlimit feature is only for
++ * control/bulk).
++ */
++
++/*
++ * Optional macros:
++ *
++ * MUSB_FLAT_REG if defined, use the core's flag register model
++ *
++ * MUSB_DEBUG 0 => absolutely no diagnostics
++ * 1 => minimal diagnostics (basic operational states)
++ * 2 => 1 + detailed debugging of interface with USB core
++ * 3 => 2 + internal debugging (e.g. every register write)
++ * 4 => 3 + shared-IRQ-related checking
++ *
++ * MUSB_DMA if defined, include DMA support.
++ * The DMA code to use is included below,
++ * so may need to be edited if a non-Inventra DMA
++ * controller is used with the Inventra core.
++ *
++ * MUSB_AHB_ID if defined, the core's identity is read from offset 0x400
++ * to verify that the expected core is present
++ *
++ * MUSB_CONFIG_PROC_FS enables statistics/state info in /proc/musbhdrc<n>
++ * where 0 <= n < number of instances of driver
++ *
++ *
++ * MUSB_HARD_IRQ try SA_INTERRUPT first when acquiring the irq (fallback to
++ * SA_SHIRQ when that fails.
++ *
++ *
++ * Options taken from linux/config.h:
++ * CONFIG_PM enables power-management
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
-+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_USB_DEBUG
-+ #define DEBUG
++#define DEBUG
+#else
-+ #undef DEBUG
++#undef DEBUG
+#endif
+
-+#include <linux/usb.h>
+
+#include "musbdefs.h"
+#include "musb_host.h"
-+#include "../core/hub.h"
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+#define HAS_USB_TT_MULTI
+#include "../core/hcd.h"
-+#endif
++#include <asm/arch/gpio.h>
++#include <asm/arch/i2c.h>
++/********************** RETURN TYPES FOR IRQ ********************************/
+
-+/** how much to "scale" response timeouts */
-+#define MUSB_MAX_RETRIES 8
++#ifdef MUSB_V26
++#define RETURN_IRQ_HANDLED return(IRQ_HANDLED)
++#define RETURN_IRQ_NONE return(IRQ_NONE)
++#endif
+
-+/*************************** Forwards ***************************/
++#ifdef MUSB_V24
++typedef void irqreturn_t;
++#define RETURN_IRQ_HANDLED return
++#define RETURN_IRQ_NONE return
++#endif
+
-+/* HCD helpers */
-+static uint8_t find_first1(unsigned int nValue);
-+static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
-+static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
-+static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis);
-+int *Urb_test;
-+extern int Urb_status;
-+/**************************************************************************
-+ *
-+ **************************************************************************/
+
-+#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY 0
++/* define this on command line */
++#ifndef MUSB_DEFAULT_IRQTYPE
++#define MUSB_DEFAULT_IRQTYPE SA_SHIRQ
+#endif
+
-+#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN 0
-+#endif
++/****************************** CONSTANTS ********************************/
+
-+#ifndef DEBUG
++#define DRIVER_AUTHOR "STMicroelectronics"
++#define DRIVER_DESC "Nomadik USB Driver"
++
++#ifndef MUSB_VERSION
++#define MUSB_VERSION "x.x"
+#endif
+
-+int mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY;
++#define DRIVER_INFO DRIVER_DESC "v" MUSB_VERSION
++#define DRIVER_NAME "HCD_NAME"
+
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE { }
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE { }
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP { }
++static const char longname[] = DRIVER_INFO;
++static const char shortname[] = DRIVER_NAME;
+
-+/**************************************************************************
-+ * Glue for virtual root hub
-+**************************************************************************/
++/* this module is always GPL, the gadget might not... */
++MODULE_DESCRIPTION (DRIVER_INFO);
++MODULE_AUTHOR (DRIVER_AUTHOR);
++MODULE_LICENSE ("GPL");
+
-+#ifdef MUSB_CONFIG_PROC_FS
-+/**
-+ * Decode an host endpoint protocol.
-+ * @param pUrn the uRb protocol shoudl be decoded
-+ * @return a const char* to the name of the protocol.
-+ */
-+char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
-+ char* pProto = "Err ";
-+
-+ switch(pThis->aLocalEnd[bEnd].bTrafficType) {
-+ case PIPE_ISOCHRONOUS: pProto = "Isoc"; break;
-+ case PIPE_INTERRUPT: pProto = "Intr"; break;
-+ case PIPE_CONTROL: pProto = "Ctrl"; break;
-+ case PIPE_BULK: pProto = "Bulk"; break;
-+ }
-+
-+ return pProto;
-+}
-+#endif
++/* time (millseconds) to wait before a restart */
++#define MUSB_RESTART_TIME 5000
++/* how many babbles to allow before giving up */
++#define MUSB_MAX_BABBLE_COUNT 10
++/* how many buss errors before stopping the operations */
++#define MUSB_MAX_VBUS_ERRORS 3
+
-+/**
-+ * Decode an urb protocol.
-+ * @param pUrn the uRb protocol shoudl be decoded
-+ * @return a const char* to the name of the protocol.
-+ */
-+char* decode_urb_protocol(struct urb* pUrb) {
-+ static char buffer[8];
-+
-+ if ( !pUrb ) {
-+ strcpy(&buffer[0], "NULL");
-+ return buffer;
-+ }
-+
-+ buffer[0]=usb_pipein(pUrb->pipe)?'I':'O';
-+ if ( usb_pipeint(pUrb->pipe) ) {
-+ strcpy(&buffer[1], " int");
-+ } else if ( usb_pipeisoc(pUrb->pipe) ) {
-+ strcpy(&buffer[1], " isoc");
-+ } else if ( usb_pipebulk(pUrb->pipe) ) {
-+ strcpy(&buffer[1], " bulk");
-+ } else if ( usb_pipecontrol(pUrb->pipe) ) {
-+ strcpy(&buffer[0], " ctl");
-+ }
-+
-+ return buffer;
-+}
++/* WEIRD KLUDGE! */
++#define IS_INVALID_ADDRESS(_x) (((unsigned long)_x)<(unsigned long)1024)
+
-+/* Root speed need to be translated (addapted)
-+ */
-+static uint8_t MGC_TranslateVirtualHubSpeed(uint8_t source) {
-+ uint8_t speed=2;
-+
-+ switch ( source ) {
-+ case 3: speed=0; break;
-+ case 2: speed=1; break;
-+ }
++#define A_IDLE 1
++#define B_IDLE 2
++#define PERIPHERAL 3
++#define HOST 4
+
-+ return speed;
-+}
++#define MAJOR_NUMBER_OTG 0x0
++#define OTG_DEEP_SLEEP 0x1
++#define OTG_WAKEUP 0x2
++#define SRP_TEST 0x3
++#define HNP_TEST 0x4
++#define PRINT_REG 0x5
++#define HOST_A_IDLE 0x6
++#define OTG_SUSPEND 0x7
++#define OTG_RESUME 0x8
+
-+/**
-+ * Timer completion callback to turn off reset and get connection speed
-+ */
-+static void MGC_HdrcResetOff(unsigned long param)
-+{
-+ uint8_t power;
-+ MGC_LinuxCd* pThis = (MGC_LinuxCd*)param;
-+ void* pBase = pThis->pRegs;
-+ unsigned long flags;
-+
-+ DBG(2, "<== Stopping root port reset...\n");
-+
-+ SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
-+ pThis->bIgnoreDisconnect = FALSE;
-+ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
++#define SUSPEND 0x0
++#define RESUME 0x1
+
-+ /* check for high-speed and set in root device if so */
-+ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+ if(power & MGC_M_POWER_HSMODE) {
-+ DBG(3, "high-speed device connected\n");
-+ pThis->bRootSpeed = 1;
-+ }
+
++/******************************* FORWARDS ********************************/
++MGC_LinuxCd *udc_address;
++struct usb_hcd *hcd1;
++int udcinitmonitorflag_isr=0,udcinitmonitorflag_init=0;
++extern void driver_change_mode_handler(uint8_t role);
++void otg_disconnect(MGC_LinuxCd *pThis);
++int dev_safe_remove=0;
++extern int Urb_status;
++struct urb *Urb_struct;
++uint8_t temp;
++uint8_t b_hnp_suspend=0;
++uint8_t b_hnp_init=0;
++void del_timer_func(void);
++extern int udc_setup(void);
++extern void udc_reset(void);
++extern void udc_resume(void);
++extern void udc_suspend(void);
++extern void udc_intr_disable(void);
++extern uint8_t host_a_idle;
++static void funct_host_notify_timer(unsigned long pThis);
++static struct timer_list notify_timer;
++extern int nomadik_udc_init(MGC_LinuxCd *pThis);
++extern void musb_reset_isr(void);
++extern void udc_disconnect_isr(void);
++extern uint8_t udc_ep0_irq(void);
++extern void udc_ep_tx_irq(uint8_t bEnd) ;
++extern void udc_ep_rx_irq(uint8_t bEnd) ;
++
++#ifndef MUSB_USE_HCD_DRIVER
+#ifdef MUSB_VIRTHUB
-+ MGC_VirtualHubPortResetDone(&(pThis->RootHub), 0,
-+ MGC_TranslateVirtualHubSpeed(pThis->bRootSpeed));
++#ifndef MUSB_V26_POST10
++/* Linux USBD glue */
++STATIC int mgc_linux_alloc_device(struct usb_device* pDevice);
++STATIC int mgc_linux_free_device(struct usb_device* pDevice);
++#endif
++STATIC int MGC_LinuxGetFrameNumber(struct usb_device* pDevice);
++#endif
+#endif
+
-+ DBG(2, "==>\n");
-+ SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+}
++STATIC void mgc_reset(MGC_LinuxCd* pThis);
++uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData);
++/* Interrupt service routine */
++#ifndef MUSB_USE_HCD_DRIVER
++STATIC irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r);
++#endif
+
-+/* see virthub.h */
-+void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bPower)
-+{
-+ DBG(2, "<==\n");
-+ if(bPower) {
-+ DBG(3, "Root port power on\n");
-+ MGC_HdrcStart((MGC_LinuxCd*)pPrivateData);
-+ } else {
-+ DBG(3, "Root port power off\n");
-+ MGC_HdrcStop((MGC_LinuxCd*)pPrivateData);
-+ }
-+ DBG(2, "==>\n");
-+}
++#ifdef MUSB_USE_HCD_DRIVER
++void mgc_hcd_flush(MGC_LinuxCd* pThis);
++#endif
+
-+/* see virthub.h */
-+void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bEnable)
-+{
-+ DBG(2, "<==\n");
-+ if (bEnable) {
-+ DBG(3, "Root port power enabled\n");
-+ } else {
-+ DBG(3, "Root port power disabled\n");
-+ }
-+
-+ DBG(2, "==>\n");
-+}
++/* HDRC functions */
++STATIC void MGC_HdrcDropResume(unsigned long pParam);
++STATIC void MGC_HdrcRestart(unsigned long pParam);
+
-+/* see virthub.h */
-+void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bSuspend)
-+{
-+ uint8_t power;
-+ MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
-+ void* pBase = pThis->pRegs;
++STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis);
+
-+ DBG(2, "<==\n");
++#ifdef MUSB_V26
++void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
++ unsigned iMemFlags, dma_addr_t* pDmaAddress);
++void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
++ void* address, dma_addr_t DmaAddress);
++#endif
+
-+ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+ if(bSuspend) {
-+ DBG(3, "Root port power suspended\n");
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
-+ } else if(power & MGC_M_POWER_SUSPENDM) {
-+ DBG(3, "Root port power resumed\n");
-+ power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME);
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
-+ WAIT_MS(20);
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, power);
-+ }
-+
-+ DBG(2, "==>\n");
-+}
++STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis);
+
-+/* see virthub.h */
-+void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bReset)
-+{
-+ uint8_t power;
-+ MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
-+ void* pBase = pThis->pRegs;
-+
-+ DBG(2, "<==\n");
++#ifdef MUSB_V26_POST10
++struct usb_bus;
++int MGC_LinuxHubSuspend(struct usb_bus *pBus);
++int MGC_LinuxHubResume(struct usb_bus *pBus);
++#endif
+
-+ power = MGC_Read8(pBase, MGC_O_HDRC_POWER) & 0xf0;
-+ if (bReset) {
-+ pThis->bIgnoreDisconnect = TRUE;
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESET);
-+ MGC_LinuxSetTimer(pThis, MGC_HdrcResetOff, (unsigned long)pThis, 60);
-+ } else if(power & MGC_M_POWER_RESET) {
-+ DBG(3, "root port reset stopped\n");
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
-+ }
++#ifdef MUSB_V26
++void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress);
++#endif
+
-+ DBG(2, "==>\n");
-+}
+
-+/**************************************************************************
-+ *
-+ **************************************************************************/
++/******************************* GLOBALS *********************************/
+
-+ /**
-+ * return the current urb for a given endpoint. Caller is responsible for
-+ * locking
-+ * @param pEnd the end point (pEnd!=NULL)
-+ * @return the urb or NULL when the end point is idle
-+ */
-+struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd) {
-+#ifdef MUSB_USE_HCD_DRIVER
-+ return pEnd->pCurrentUrb;
-+#else
-+ DBG(8 ,"GetCurrentUrb urb_list_ptr:0x%p \n",&(pEnd->urb_list));
-+ DBG(8 ,"GetCurrentUrb urb_list->next:0x%p \n",pEnd->urb_list.next);
-+ DBG(8 ,"GetCurrentUrb urb_list->prev:0x%p \n",pEnd->urb_list.prev);
-+ return list_empty(&(pEnd->urb_list)) ? NULL
-+ : list_entry(pEnd->urb_list.next, struct urb, urb_list);
-+#endif
-+}
+
-+/**
-+ * Test whether a local endpoint is idle.
-+ * @param pEnd the endpoint
-+ * @return !=0 when idle, 0 otherwise
-+ */
-+int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd)
++MGC_LinuxCd *hcd_to_musbstruct(void *ptr)
+{
+#ifdef MUSB_USE_HCD_DRIVER
-+ return (pEnd->pCurrentUrb)==NULL;
++ return (MGC_LinuxCd*)((struct usb_hcd *)ptr)->hcd_priv;
+#else
-+ return list_empty(&pEnd->urb_list);
-+#endif
++ return (MGC_LinuxCd*)ptr;
++#endif
+}
+
-+
-+void mgc_ep_idle(MGC_LinuxLocalEnd* pEnd) {
++struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis)
++{
+#ifdef MUSB_USE_HCD_DRIVER
-+ pEnd->pCurrentUrb=NULL;
++ return container_of((void*)pThis, struct usb_hcd, hcd_priv);
+#else
-+ INIT_LIST_HEAD(&(pEnd->urb_list));
-+#endif
++ return NULL;
++#endif
+}
+
++/******************************* GLOBALS *********************************/
++
++unsigned int MGC_nIndex = 0;
++
++static const char MGC_HcdName [] = "musb-hcd";
+
++#ifndef MUSB_USE_HCD_DRIVER
+/**
-+ * Dequeue an urb from an endpoint.
-+ * @param pEnd the endpoint
-+ * @param pUrb the urb to be removed
++ * Virtual hub functions: Linux USBD calls these
+ */
-+static int mgc_ep_dequeue_urb(MGC_LinuxLocalEnd* pEnd, struct urb *pUrb,MGC_LinuxCd* pThis)
++#ifdef MUSB_VIRTHUB
++static struct usb_operations MGC_LinuxOperations =
+{
-+ int rc=0;
++#ifndef MUSB_V26_POST10
++ .allocate = mgc_linux_alloc_device,
++ .deallocate = mgc_linux_free_device,
++#endif
+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ if ( pEnd->pCurrentUrb==pUrb ) {
-+ pUrb->hcpriv=NULL;
-+ pEnd->pCurrentUrb=NULL;
-+ } else {
-+ rc=-EINVAL;
-+ ERR("*** Trying to dequeue pUrb=%p from ep%d while pEnd->pCurrentUrb=%p\n",
-+ pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
-+ }
-+#else
-+ pUrb->hcpriv=NULL;
-+ list_del_init(&pUrb->urb_list);
++ .get_frame_number = MGC_LinuxGetFrameNumber,
++
++#ifdef MUSB_V24
++ .submit_urb = MGC_LinuxSubmitUrb24,
+#endif
+
-+ /* clear endpoint status (preserving the softstate for find_end() ) */
-+ mgc_ep_linux_clear(pEnd,pThis);
++#ifdef MUSB_V26
++ .submit_urb = MGC_LinuxSubmitUrb26,
++#endif
+
-+ DBG(1, "==> dequeued pUrb=%p from pEnd->bEnd=%d rc=%d\n",
-+ pUrb, pEnd->bEnd, rc);
-+ return rc=0;
-+}
++#ifdef MUSB_V24
++ .unlink_urb = MGC_LinuxUnlinkUrb24,
++#endif
++#ifdef MUSB_V26
++ .unlink_urb = MGC_LinuxUnlinkUrb26,
++#endif
+
-+/**
-+ * @return 0 success, != when the ep is busy with another request
-+ */
-+static int mgc_ep_enqueue_urb(MGC_LinuxLocalEnd* pEnd, struct urb* pUrb)
++#ifdef MUSB_V26
++ .buffer_alloc = MGC_LinuxBufferAlloc,
++ .buffer_free = MGC_LinuxBufferFree,
++ .disable = mgc_linux_disable,
++#endif
++
++#ifdef MUSB_V26_POST10
++ .hub_suspend = MGC_LinuxHubSuspend,
++ .hub_resume = MGC_LinuxHubResume,
++#endif
++};
++#endif
++#endif
++
++const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE] = {
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
++ 0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
++ 0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf,
++ 0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf,
++ 0xef, 0xf7, 0xfb, 0xfd, 0x7e
++};
++
++
++
++int otg_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++int otg_open (struct inode *inode, struct file *file);
++int otg_close (struct inode *inode, struct file *file);
++extern void otg_deep_sleep(void);
++extern void otg_wakeup(void);
++extern void set_host_a_idle(void);
++extern void hnp_initiate(void);
++extern void srp_initiate(void);
++
++static struct file_operations otg_fops = {
++ owner: THIS_MODULE,
++ read: NULL,
++ write: NULL,
++ ioctl: otg_ioctl,
++ open: otg_open,
++ flush: NULL,
++ release: otg_close,
++};
++
++
++/******************************* GLOBALS *********************************/
++
++int otg_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
-+ int rc=0;
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ if ( pEnd->pCurrentUrb ) {
-+ ERR("*** urb=%p, ep=%d wile busy with urb=%p, this is BAD (tm)\n",
-+ pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
-+ rc=-EBUSY;
-+ } else {
-+ pEnd->pCurrentUrb=pUrb;
++ /* to prevent compiler warnings */
++ inode=inode;
++ filp=filp;
++ arg=arg;
++
++ switch(cmd) {
++
++ case OTG_DEEP_SLEEP:
++ del_timer(¬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; bEnd<MUSB_C_NUM_EPS-1; bEnd++) {
-+ if ( MGC_GetCurrentUrb(&pThis->aLocalEnd[bEnd])==pUrb ) {
-+ return &pThis->aLocalEnd[bEnd];
-+ }
-+ }
-+
-+ return NULL;
++ /* to prevent compiler warnings */
++ inode=inode;
++ file=file;
++
++ return 0;
++}
++
++
++int otg_close (struct inode *inode, struct file *file)
++{
++ /* to prevent compiler warnings */
++ inode = inode;
++ file = file;
++
++ return 0;
+}
+
++
++
++
++
+/**************************************************************************
-+ *
-+ **************************************************************************/
++ * HDRC functions
++**************************************************************************/
+
-+void mgc_complete_urb(MGC_LinuxCd *pThis, struct urb *pUrb) {
-+ /* give it back */
-+ usb_put_urb(pUrb);
-+ if (pUrb->status) {
-+ DBG(1, "completing urb=%p,status=%d\n", pUrb, pUrb->status);
-+ }
++/**
++ * Timer completion callback to finish resume handling started in ISR
++ * @param pParam the driver instance
++ */
++STATIC void MGC_HdrcDropResume(unsigned long pParam)
++{
++ uint8_t power;
++ MGC_LinuxCd* pThis = (MGC_LinuxCd*)pParam;
++ void* pBase = pThis->pRegs;
+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ mgc_hcd_complete_urb(pThis, pUrb);
-+#else
-+ if ( pUrb->complete ) {
-+ COMPLETE_URB(pUrb, NULL);
-+ }
-+#endif
++ DBG(2, "<==\n");
+
-+ if (pUrb->status) {
-+ DBG(1, "done completing pUrb=%p\n", pUrb);
-+ }
++ power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME);
++
++#ifdef MUSB_VIRTHUB
++ MGC_VirtualHubPortResumed(&(pThis->RootHub), 0);
++#endif
+}
+
+/**
-+ * complete an urb. Since urb completion generally post new urbs via
-+ * submit urn, this make sure the ep won't kickstart it during the
-+ * completion.
-+ *
-+ * @param pEnd the end point urb is posted to
-+ * @param pUrb the urb to complete !=NULL
-+ * @return 0 success
++ * Timer completion callback to request session again
++ * (to avoid self-connecting)
++ * @param pParam the driver instance
+ */
-+static inline int mgc_linux_complete_urb(MGC_LinuxCd *pThis,
-+ MGC_LinuxLocalEnd* pEnd, struct urb *pUrb)
++STATIC void MGC_HdrcRestart(unsigned long pParam)
+{
-+
-+ int periodic=mgc_urb_is_periodic(pUrb);
-+ int status=periodic; /* 0 needs start next */
-+ int error=(pUrb->status==-ENOENT) || (pUrb->status==-ECONNRESET) ||
-+ (pUrb->status==-ESHUTDOWN) || (pUrb->status==-ETIMEDOUT)
-+ || (pUrb->status==-EBUSY);
-+
-+ DBG(2, "<== completing URB %p, on pEnd->bEnd=%d status=%d, proto=%s\n",
-+ pUrb, pEnd->bEnd, pUrb->status, decode_urb_protocol(pUrb));
-+
-+ if ( error && periodic ) {
-+ pEnd->bIsClaimed=FALSE;
-+ }
++ MGC_HdrcStart((MGC_LinuxCd*)pParam);
++}
+
-+ /* prevents locking&kickstarting */
-+ pEnd->bBusyCompleting=1;
++/* -------------------------------------------------------------------------
++ *
++ * ------------------------------------------------------------------------ */
+
-+ mgc_complete_urb(pThis, pUrb);
-+
-+#ifdef MUSB_V24
-+ /* Under 2.4 interrupt IN URBs must be re-submitted from the driver
-+ * unless they are unlinked; 2.6 urbs do that from the completition
-+ * routine. ENODEV means we raced disconnect() */
-+ if ( !error && periodic ) {
-+ DBG(1, "periodic pUrb=%p, proto=%s, (status=%d)\n", pUrb,
-+ decode_urb_protovol(pUrb), pUrb->status);
-+ status=mgc_schedule_urb(pThis, pEnd, pUrb);
-+ if ( (status!= 0) && (status != -ENODEV) ) {
-+ DBG(3, "error resubmitting intr URB %p (status=%d)\n",
-+ pUrb, status);
-+ }
-+
++/**
++ * Load an HDRC FIFO
++ *
++ * @param pBase base address of HDRC
++ * @param bEnd local endpoint
++ * @param wCount how many bytes to load
++ * @param pSource data buffer
++ */
++void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd,
++ uint16_t wCount, const uint8_t* pSource)
++{
++ uint16_t wIndex, wIndex32;
++ uint16_t wCount32 = wCount >> 2;
++ uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd);
++ DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pSrc=%p\n",
++ pBase, bEnd, wCount, pSource);
++
++#ifdef MUSB_PARANOID
++ if ( IS_INVALID_ADDRESS(pSource) ) {
++ ERR("loading fifo from a null buffer; why did u do that????\n");
++ return;
+ }
-+#else
-+ status=0; /* kickstart next */
+#endif
+
-+ /* allows locking&kickstarting again */
-+ pEnd->bBusyCompleting=0;
++ /* doublewords when possible */
++ for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) {
++ MGC_Write32(pBase, bFifoOffset, *((uint32_t*)&(pSource[wIndex])));
++ }
+
-+ DBG(2, "==> status=%d, periodic=%d\n", status, periodic);
-+ return status;
++ for(; wIndex < wCount; wIndex++) {
++ MGC_Write8(pBase, bFifoOffset, pSource[wIndex]);
++ }
+}
-+
++
+/**
-+ * Start transmit. Caller is responsible for locking the ep.
-+ * On EP0 only PING is disabled.
++ * Unload an HDRC FIFO
+ *
-+ * @param pThis instance pointer
++ * @param pBase base address of HDRC
+ * @param bEnd local endpoint
++ * @param wCount how many bytes to unload
++ * @param pDest data buffer
+ */
-+void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd)
++void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd,
++ uint16_t wCount, uint8_t* pDest)
+{
-+ uint16_t wCsr;
-+ uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+
-+ DBG(2, "<== bEnd=%d ==>\n", bEnd);
-+ /* NOTE: no locks here; caller should lock */
-+ MGC_SelectEnd(pBase, bEnd);
-+ if(bEnd) {
-+ wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
-+ wCsr |= MGC_M_TXCSR_TXPKTRDY;
-+ MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
-+ } else {
-+ MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
-+ MGC_M_CSR0_H_NO_PING | MGC_M_CSR0_H_SETUPPKT | MGC_M_CSR0_TXPKTRDY);
-+ }
-+}
-+
-+/**************************************************************************
-+ *
-+ **************************************************************************/
++ uint16_t wIndex=0, wIndex32;
++ uint16_t wCount32 = wCount >> 2;
++ uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd);
+
-+ /**
-+ * return the buffer associated to an urb (map it too)
-+ */
-+static inline uint8_t* get_urb_buffer(struct urb* pUrb) {
-+ uint8_t *pBuffer=NULL;
-+
+#ifdef MUSB_PARANOID
-+ if ( !pUrb ) {
-+ return NULL;
++ if ( IS_INVALID_ADDRESS(pDest) ) {
++ ERR("unloading fifo from a null buffer\n");
++ return;
+ }
+#endif
+
-+ pBuffer=pUrb->transfer_buffer;
-+#ifndef MUSB_LINUX_MV21
-+ if ( !pBuffer ) {
-+ pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
++ DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pDest=%p\n", pBase, bEnd,
++ wCount, pDest);
++
++ /* doublewords when possible */
++ for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) {
++ *((uint32_t*)&(pDest[wIndex])) = MGC_Read32(pBase, bFifoOffset);
+ }
-+#endif
+
-+ return pBuffer;
++ while(wIndex < wCount) {
++ pDest[wIndex++]=MGC_Read8(pBase, bFifoOffset);
++ }
+}
-+
-+/**
-+ * Xmit a packet. pEnd->dwOffset is updated as well
-+ * @param pThis
-+ * @param bEnd the EP urb is queued to
++
++/* -------------------------------------------------------------------------
++ *
++ * ------------------------------------------------------------------------ */
++
++/**
++ * Stop the host controller driver. Stop the controller and disconnect the
++ * virtual hub.
++ * @param pThis the controller
++ * @param vberr !=0 if a VBUs error was discovered.
+ */
-+static uint8_t mgc_linux_packet_tx(MGC_LinuxCd* pThis, uint8_t bEnd) {
-+ uint32_t wLength=0;
-+ uint8_t bDone = FALSE;
-+ uint8_t *pBase = (uint8_t*)pThis->pRegs;
-+ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+ struct urb* pUrb=MGC_GetCurrentUrb(pEnd);
-+ uint8_t *pBuffer=get_urb_buffer(pUrb);
-+ int nPipe = pUrb ? pUrb->pipe : 0;
++static void hdrc_stop_host(MGC_LinuxCd* pThis, int vberr)
++{
++ MGC_HdrcStop(pThis);
+
-+ DBG(2, "<== bEnd=%d\n", bEnd);
++#ifdef MUSB_VIRTHUB
++ MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
++ pThis->pRootDevice = NULL;
++ mgc_hcd_flush(pThis);
++#endif
+
-+ /* abort the transfer */
-+ if ( !pBuffer ) {
-+ ERR("***> no buffer was given, BAD things are happening (TM)!\n");
-+ return TRUE;
-+ }
++}
+
-+ /* see if more transactions are needed */
-+#ifdef MUSB_DMA
-+ if(pEnd->pDmaChannel) {
-+ if (MGC_DMA_STATUS_FREE ==
-+ pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel)
-+ ) {
-+ pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
-+ }
-+ } else {
-+ pEnd->dwOffset += pEnd->dwRequestSize;
-+ }
-+#else
-+ pEnd->dwOffset += pEnd->dwRequestSize;
++/**
++ * Interrupt Service Routine to record USB "global" interrupts.
++ * Since these do not happen often and signify things of
++ * paramount importance, it seems OK to check them individually;
++ * there is an ORDER to perform the tests check p35 of the MUSBHDRC
++ * manual.
++ *
++ * @param pThis instance pointer
++ * @param bIntrUSB register contents
++ * @param devctl
++ * @param power
++ */
++static int mgc_hdrc_service_usb_stage0(MGC_LinuxCd* pThis, uint8_t bIntrUSB,
++ uint8_t devctl, uint8_t power)
++{
++ int handled=0;
++#ifdef MUSB_HOST
++ uint8_t bSpeed = 1;
++ uint8_t bHubSpeed = 2;
+#endif
++ uint8_t bResetBabble = FALSE;
++ uint8_t* pBase = (uint8_t*)pThis->pRegs;
+
-+ if (usb_pipeisoc(nPipe)) {
-+ /* isoch case */
-+ if(++pEnd->dwIsoPacket >= pUrb->number_of_packets) {
-+ bDone = TRUE;
-+ } else {
-+ pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
-+ wLength = pUrb->iso_frame_desc[pEnd->dwIsoPacket].length;
++ /* in host mode when a device resume me (from power save)
++ * in device mode when the host resume me; it shold not change
++ * "identity".
++ */
++ if (bIntrUSB & MGC_M_INTR_RESUME) {
++ handled++;
++ DBG(2, "RESUME\n");
++
++ if (devctl & MGC_M_DEVCTL_HM) {
++#ifdef MUSB_HOST
++ printk("Host Mode : resume\n");
++ power &= ~MGC_M_POWER_SUSPENDM;
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
++ MGC_LinuxSetTimer(pThis, MGC_HdrcDropResume,
++ (unsigned long)pThis, 40);
++#endif
+ }
-+ } else {
-+ pBuffer += pEnd->dwOffset;
-+ wLength = min((uint32_t)(pEnd->wPacketSize),
-+ (uint32_t)(pUrb->transfer_buffer_length - pEnd->dwOffset));
-+ if(pEnd->dwOffset >= pUrb->transfer_buffer_length) {
-+ /* sent everything; see if we need to send a null */
-+ if(!((pEnd->dwRequestSize == pEnd->wPacketSize) &&
-+ (pUrb->transfer_flags & USB_ZERO_PACKET)))
-+ {
-+ bDone = TRUE;
-+ }
++ else {
++ udc_resume();
++ printk("Device Mode : resume\n");
+ }
+ }
+
-+ if (bDone) {
-+ pUrb->status=0;
-+ } else if ( wLength ) { /* @assert bDone && !wLength */
-+ MGC_HdrcLoadFifo(pBase, bEnd, wLength, pBuffer);
-+ pEnd->dwRequestSize = wLength;
-+ }
++ /* p35 MUSBHDRC manual for the order of the tests */
++ if (bIntrUSB & MGC_M_INTR_SESSREQ) {
++ DBG(2, "SESSION_REQUEST\n");
+
-+#ifdef MUSB_CONFIG_PROC_FS
-+ pEnd->dwTotalTxBytes += pEnd->dwRequestSize;
-+ pEnd->dwTotalTxPackets++;
++ /* NOTE i might get a sesison request WHILE switchign between B and A
++ * device investigatge about that; check p35 of the manual
++ */
++#ifdef MUSB_PARANOID
++ if ( HDRC_IS_DEV(pThis) ) {
++ ERR("Received a SESSION_REQUEST when connected to the B end; am I switching?!\n");
++ }
+#endif
+
-+ DBG(2, "==> bDone=%d\n", bDone);
-+ return bDone;
-+}
-+
-+
-+/**
-+ * Receive a packet (or part of it).
-+ * @requires pThis->Lock locked
-+ * @param pThis
-+ * @param bEnd
-+ * @param bIsochError
-+ * @return TRUE if URB is complete
-+ */
-+static uint8_t mgc_linux_packet_rx(MGC_LinuxCd* pThis, uint8_t bEnd,
-+ uint16_t wRxCount, uint8_t bIsochError)
-+{
-+ uint16_t wLength, wCsr;
-+ uint8_t bDone = FALSE;
-+ uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+ struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
-+ uint8_t* pBuffer=get_urb_buffer(pUrb);
-+ int nPipe = pUrb ? pUrb->pipe : 0;
++ /* time critical code (turn on VBUS); inherent race condition */
++ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
++ pThis->bEnd0Stage = MGC_END0_START;
++
++ handled++;
+
-+ DBG(2, "<== end %d RxCount=%04x\n", bEnd, wRxCount);
++ }
++
++ /* VBUSError is bad, shutdown & go to error mode and ignore
++ * the other interrups; p35 MUSBHDRC manual for the order
++ of the tests */
++ if (bIntrUSB & MGC_M_INTR_VBUSERROR) {
++ handled++;
+
+#ifdef MUSB_PARANOID
-+ if ( !pUrb || ((pUrb->transfer_buffer_length - pEnd->dwOffset)<0) ) {
-+ ERR("***> Rx error: pUrb=%p, pUrb->transfer_buffer_length=%d pEnd->dwOffset=%d\n", \
-+ pUrb, pUrb->transfer_buffer_length, pEnd->dwOffset );
-+ return TRUE;
-+ }
++ if ( !(devctl & MGC_M_DEVCTL_HM) ) {
++ ERR("Received a MGC_M_INTR_VBUSERROR when connected to the B end!\n");
++ hdrc_stop_host(pThis, FALSE);
++ return handled;
++ }
+#endif
+
-+ DBG(3, "bEnd=%d, pUrb->transfer_flags=0x%x pUrb->transfer_buffer=%p\n", \
-+ bEnd, pUrb->transfer_flags, pUrb->transfer_buffer);
-+ DBG(3, "pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, wRxCount=%d\n",
-+ pUrb->transfer_buffer_length, pEnd->dwOffset, wRxCount);
-+
-+ /* abort the transfer */
-+ if ( !pBuffer ) {
-+ ERR("***> pBuffer=NULL, BAD things are happening (TM)!\n");
-+ return TRUE;
-+ }
-+
-+ /* unload FIFO */
-+ if( usb_pipeisoc(nPipe) ) {
-+ /* isoch case */
-+ pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
-+ wLength = min((unsigned int)wRxCount,
-+ pUrb->iso_frame_desc[pEnd->dwIsoPacket].length);
-+ pUrb->actual_length += wLength;
-+
-+ /* update actual & status */
-+ pUrb->iso_frame_desc[pEnd->dwIsoPacket].actual_length = wLength;
-+ if(bIsochError) {
-+ pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_CRC;
-+ pUrb->error_count++;
-+ } else {
-+ pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_NOERROR;
++ DBG(2, "V_BUS ERROR??? this is bad (TM)\n");
++ if ( pThis->bVbusErrors++ > MUSB_MAX_VBUS_ERRORS ) {
++ printk("Vbus Error\n");
++ hdrc_stop_host(pThis, TRUE);
++ MUSB_ERR_MODE(pThis, MUSB_ERR_VBUS);
+ }
-+
-+ /* see if we are done */
-+ bDone = (++pEnd->dwIsoPacket >= pUrb->number_of_packets);
++ }
+
-+ DBG(3, "pEnd->dwIsoPacket=%d, pUrb->number_of_packets=%d, wLength=%d\n",
-+ pEnd->dwIsoPacket, pUrb->number_of_packets, wLength);
-+ DEBUG_CODE(3, if ( bDone ) { \
-+ INFO("completing %d-packet isoch URB; len=%x, errors=%d\n", \
-+ pUrb->number_of_packets, pUrb->actual_length, pUrb->error_count); \
-+ } );
-+ } else {
-+ DBG(3, "(bEnd=%d), wRxCount=%d, pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, pEnd->wPacketSize=%d\n",
-+ bEnd, wRxCount, pUrb->transfer_buffer_length, pEnd->dwOffset, pEnd->wPacketSize);
++ /* connect is valid only when in host mode; ignore it if in device mode;
++ p35 MUSBHDRC manual for the order of the tests */
+
-+ /* non-isoch */
-+ pBuffer += pEnd->dwOffset;
-+ wLength = min((unsigned int)wRxCount,
-+ pUrb->transfer_buffer_length - pEnd->dwOffset);
-+ pUrb->actual_length += wLength;
-+ pEnd->dwOffset += wLength;
-+
-+ /* see if we are done */
-+ bDone = (pEnd->dwOffset >= pUrb->transfer_buffer_length)
-+ || (wRxCount < pEnd->wPacketSize);
-+
-+ DEBUG_CODE(3, if ( bDone ) { \
-+ INFO("will complete URB; pUrb=%p (%s) len=%x, errors=%d\n", \
-+ pUrb, decode_urb_protocol(pUrb), pUrb->actual_length, \
-+ pUrb->error_count); \
-+ } );
-+ }
+
-+ if ( wLength ) {
-+ MGC_HdrcUnloadFifo(pBase, bEnd, wLength, pBuffer);
-+ }
-+
-+#ifdef MUSB_CONFIG_PROC_FS
-+ pEnd->dwTotalRxBytes += wLength;
-+ pEnd->dwTotalRxPackets++;
++ if(bIntrUSB & MGC_M_INTR_CONNECT) {
++ handled++;
++ Urb_status=0;
++
++ if(host_a_idle==1){
++ host_a_idle=0;
++ }
++ DBG(2, "RECEIVED A CONNECT (goto host mode)\n");
++ printk("connect interrupt\n");
++#ifdef MUSB_PARANOID
++ if ( !(devctl & MGC_M_DEVCTL_HM) ) {
++ ERR("Received a CONNECT when connected to the B end!\n");
++ }
+#endif
-+
-+ if( wRxCount <= wLength ) { /* test for short packet */
-+ wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
-+ MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
-+ wCsr & ~MGC_M_RXCSR_RXPKTRDY);
-+ }
-+ if ( bEnd && bDone ) {
-+ pUrb->status=0;
-+ }
-+
-+ DBG(2, "==> bDone=%d\n", bDone);
-+ return bDone;
-+}
++ MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
++ MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
+
-+/* *************************************************************************
-+ *
-+ **************************************************************************/
++#ifdef MUSB_HOST
++ pThis->pRootDevice = NULL;
++ pThis->bEnd0Stage = MGC_END0_START;
+
-+/**
-+ * Find first (lowest-order) 1 bit
-+ * @param nValue value in which to search
-+ * @return bit position (0 could mean no bit; caller should check)
-+ */
-+static uint8_t find_first1(unsigned int nValue)
-+{
-+ uint8_t bResult;
-+ unsigned int nWork = nValue;
++ /* reset the addres... probably not needed*/
++ MGC_Write8(pThis->pRegs, MGC_O_HDRC_FADDR, 0);
++ /* flush endpoints when transitioning from Device Mode*/
++ if ( MUSB_IS_A_IDLE(pThis) ) {
++ uint8_t bEnd;
+
-+ for(bResult = 0; bResult < 32; bResult++) {
-+ if(nWork & 1) {
-+ return bResult;
++ for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++ MGC_HdrcStopEnd(pThis, bEnd);
++ }
+ }
-+ nWork >>= 1;
-+ }
-+
-+ return bResult;
-+}
+
-+/**
-+ * @param nPipe
-+ */
-+static inline char *pipe_type(const unsigned int nPipe) {
-+ if ( usb_pipeisoc(nPipe) ) {
-+ return "isoc";
-+ } else if ( usb_pipebulk(nPipe) ) {
-+ return "bulk";
-+ } else if ( usb_pipeint(nPipe) ) {
-+ return "int";
-+ } else {
-+ return "cntl";
-+ }
-+}
+
-+/** Calculate the interval (or NAK limit for bulk) for isoc and
-+ * inter requests.
-+ * @param pUrb the urb interval should be determined for
-+ * @return the interval
-+ */
-+static uint8_t hdrc_interval(struct urb* pUrb) {
-+ const unsigned int nPipe = pUrb->pipe;
-+ uint8_t bInterval = (uint8_t)pUrb->interval;
-+
-+ if( usb_pipeint(nPipe) ) {
-+ /* correct interval for high-speed */
-+ if((USB_SPEED_HIGH == ((uint8_t)pUrb->dev->speed)) && (pUrb->interval > 255)) {
-+ bInterval = find_first1(pUrb->interval);
-+ }
-+ } else {
-+ /* normalize value */
-+ if(pUrb->interval > 16) {
-+ bInterval = find_first1(pUrb->interval);
-+ }
-+
-+ if(usb_pipeisoc(nPipe) && (bInterval < 1)) {
-+ bInterval = 1;
++ if(devctl & MGC_M_DEVCTL_LSDEV) {
++ bSpeed = 3;
++ bHubSpeed = 0;
++ } else if(devctl & MGC_M_DEVCTL_FSDEV) {
++ /* NOTE: full-speed is "speculative" until reset */
++ bSpeed = 2;
++ bHubSpeed = 1;
+ }
+
-+ if( usb_pipebulk(nPipe) && (bInterval < 2)) {
-+ /* this is the NACK time */
-+ bInterval = 0;/*16;*/
++ pThis->bRootSpeed = bSpeed;
++ if(pThis->bIsMultipoint) {
++ /* set speed for EP0 */
++ MGC_SelectEnd(pBase, 0);
++ MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0,
++ (bSpeed << 6));
+ }
-+ }
-+
-+ DBG(2, "pipe_type=%s bInterval=%d\n", pipe_type(nPipe), bInterval);
-+
-+ return bInterval;
-+}
-+
-+/**
-+ * @param pUrb
-+ */
-+static inline uint8_t hdrc_type(struct urb* pUrb) {
-+ uint8_t bStdType = 0;
-+ const unsigned int nPipe = pUrb->pipe;
-+
-+ if(usb_pipeisoc(nPipe)) {
-+ bStdType = 1;
-+ } else if(usb_pipeint(nPipe)) {
-+ bStdType = 3;
-+ } else if( usb_pipebulk(nPipe) ) {
-+ bStdType = 2;
-+ }
-+
-+ return bStdType;
-+}
+
-+/**
-+ * program hdrc_registers for the device address of a given urb.
-+ * @param pTjos
-+ * @param pUrb
-+ * @param bEnd
-+ * @param bXmt
-+ */
-+static void hdrc_set_address(MGC_LinuxCd* pThis, struct urb* pUrb, uint8_t bEnd,
-+ unsigned int bXmt)
-+{
-+#ifdef MUSB_LINUX_MV21
-+ struct usb_device* pParent;
++ MUSB_HST_MODE(pThis);
++
++ /* indicate new connection to OTG machine */
++ MGC_VirtualHubPortConnected(&(pThis->RootHub), 0,
++ bHubSpeed);
+#endif
-+ uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+ uint8_t bAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
-+ uint8_t bHubAddr = 0, bHubPort = 0, bIsMulti = FALSE;
++ }
+
++ /* saved one bit: bus reset and babble share the same bit;
++ * If I am host is a babble! i must be the only one allowed
++ * to reset the bus; when in otg mode it means that I have
++ * to switch to device
++ */
++ if (bIntrUSB & MGC_M_INTR_RESET) {
+
-+ /* NOTE: there is always a parent due to the virtual root hub */
-+ bHubAddr = (uint8_t)pUrb->dev->parent->devnum;
-+ /* but not if parent is our virtual root hub */
-+ if(bHubAddr == pThis->RootHub.bAddress) {
-+ bHubAddr = 0;
-+ }
++#ifndef MUSB_OTG
+
-+#ifdef MUSB_LINUX_MV21
-+ /* parent hub address */
-+ pParent = pUrb->dev->parent;
-+
-+ /* this distribution doesn't support directly, so try to find ourselves */
-+ if((USB_SPEED_HIGH!=((uint8_t)pUrb->dev->speed)) &&
-+ (pParent->devnum != pThis->RootHub.bAddress))
-+ {
-+ int nChild;
-+ struct usb_device* pDevice;
-+
-+ /* walk up to first high-speed hub and remember our subtree's child */
-+ pDevice = pUrb->dev;
-+ while(pParent && (USB_SPEED_HIGH != pParent->speed) &&
-+ (pParent->devnum != pThis->RootHub.bAddress))
-+ {
-+ pDevice = pParent;
-+ pParent = pParent->parent;
-+ }
-+
-+ if(pParent && (pParent->devnum != pThis->RootHub.bAddress)) {
-+ /* correlate to port and check for multi-TT */
-+ for(nChild = 0; nChild < pParent->maxchild; nChild++) {
-+ if(pParent->children[nChild] == pDevice) {
-+ bHubPort = nChild + 1;
-+ bIsMulti = (2 == pParent->descriptor.bDeviceProtocol);
-+ break;
-+ }
-+ }
++ /* This is added since, Mentor IP same bit is shared for RESET and BABBLE.
++ * In host mode if this bit is set to indicate BABBLE, but when this bit
++ * get set the controller clears the session bit and the host mode bit in
++ * device control register and driver reads it as RESET and tries to enter
++ * in device mode. So if OTG is not set we will check the driver status and
++ * the appropriate action.
++ */
++
++ if(MUSB_IS_HST(pThis)){
++ bResetBabble = TRUE;
+ }
-+ }
+#else
-+ /* if tt pointer, use its info */
-+ if(pUrb->dev->tt) {
-+ bHubPort = (uint8_t)pUrb->dev->ttport;
-+#ifdef HAS_USB_TT_MULTI
-+ bIsMulti = (uint8_t)pUrb->dev->tt->multi;
-+#endif
-+ }
++ bResetBabble = devctl & MGC_M_DEVCTL_HM;
+#endif
-+
-+ if ( bIsMulti ) {
-+ bHubAddr |=0x80;
-+ }
-+
-+ /* tx address */
-+ if(pThis->bIsMultipoint) {
-+ /* target addr & hub addr/port */
-+ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR),
-+ bAddress);
-+ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR),
-+ bHubAddr);
-+ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT),
-+ bHubPort);
-+
-+ /* also, try Rx (this is a bug ion the core: I always need to to do
-+ * both (at least for ep0), needs to be changed when the core is
-+ * fixed */
-+ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR),
-+ bAddress);
-+ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR),
-+ bHubAddr);
-+ MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT),
-+ bHubPort);
-+ } else {
-+ /* non-multipoint core */
-+
-+ MGC_Write8(pBase, 0x80 + 8*bEnd, bAddress);
-+ MGC_Write8(pBase, 0x84 + 8*bEnd, bAddress);
-+
-+ }
++ DBG(2, "BUS RESET\n");
+
-+ DBG(2, "end %d, device %d, parent %d, port %d, multi-tt: %d, speed:%d\n", \
-+ bEnd, pUrb->dev->devnum, bHubAddr, bHubPort, bIsMulti, pUrb->dev->speed );
-+}
++ if (bResetBabble) {
++ printk("Host Mode : reset\n");
++ hdrc_stop_host(pThis, FALSE);
++ /* restart session after cooldown unless threshold reached */
++ if( pThis->nBabbleCount++ < MUSB_MAX_BABBLE_COUNT) {
++ MGC_LinuxSetTimer(pThis, MGC_HdrcRestart,
++ (unsigned long)pThis, MUSB_RESTART_TIME);
++ }
++ } else {
+
-+/**
-+ * @param pThis
-+ * @param pUrb
-+ * @param bEnd
-+ * @param bXmt
-+ */
-+static void hdrc_set_protocol(MGC_LinuxCd* pThis, struct urb* pUrb,
-+ uint8_t bEnd, unsigned int bXmt)
-+{
-+ uint8_t reg;
-+ uint8_t bStdType = hdrc_type(pUrb);
-+ unsigned int nPipe = pUrb->pipe;
-+ uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+
-+ reg = (bStdType << 4 ) |
-+ (((uint8_t)usb_pipeendpoint(nPipe)) & 0xf);
-+ switch( ((uint8_t)pUrb->dev->speed) ) {
-+ case USB_SPEED_LOW:
-+ reg |= 0xc0;
-+ break;
-+ case USB_SPEED_FULL:
-+ reg |= 0x80;
-+ break;
-+ default:
-+ reg |= 0x40;
-+ }
-+
-+ if ( bXmt ) {
-+ if(bEnd) {
-+ MGC_WriteCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd, reg);
-+ } else if(pThis->bIsMultipoint) {
-+ MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
-+ }
-+ } else {
-+ if(bEnd) {
-+ MGC_WriteCsr8(pBase, MGC_O_HDRC_RXTYPE, bEnd, reg);
-+ } else if(pThis->bIsMultipoint) {
-+ MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
-+ }
-+ }
-+}
++ del_timer(¬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
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+#ifndef __MUSB_HSFC_DEFS_H__
-+#define __MUSB_HSFC_DEFS_H__
++#include <asm/uaccess.h>
+
-+#define MGC_MAX_USB_ENDS 16
++#include <linux/kernel.h>
++#include <linux/proc_fs.h>
+
-+#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */
++#include <linux/usb.h>
++#include "musbdefs.h"
++#include "musb_ioctl.h"
+
-+#define MGC_M_FIFO_EP0 0x20
++/* ----------------------------------------------------------------------- */
+
-+/*
-+ * MUSBHSFC Register map
-+ */
++#if MUSB_DEBUG > 0
++static int atoi(char* buffer, int base, int len) {
++ int result=0, digit=0;
+
-+/* Common USB registers */
++ while ( len-->0 && (*buffer) ) {
++ digit=((*buffer>='0') && (*buffer<='9'))
++ ? *buffer-'0'
++ : ((*buffer>='a') && (*buffer<='f'))
++ ? *buffer-'a'
++ : -1;
+
-+#define MGC_O_HSFC_FADDR 0x00 /* 8-bit */
-+#define MGC_O_HSFC_POWER 0x01 /* 8-bit */
++ if ( digit<0 ) {
++ break;
++ }
+
-+#define MGC_O_HSFC_INTRIN 0x02 /* 16-bit */
-+#define MGC_O_HSFC_INTROUT 0x04
-+#define MGC_O_HSFC_INTRINE 0x06
-+#define MGC_O_HSFC_INTROUTE 0x08
-+#define MGC_O_HSFC_INTRUSB 0x0A /* 8 bit */
-+#define MGC_O_HSFC_INTRUSBE 0x0B /* 8 bit */
-+#define MGC_O_HSFC_FRAME 0x0C
-+#define MGC_O_HSFC_INDEX 0x0E /* 8 bit */
-+#define MGC_O_HSFC_TESTMODE 0x0F /* 8 bit */
++ buffer++;
++ result=result*base+digit;
++ }
+
-+/* These are actually indexed: */
-+#define MGC_O_HSFC_TXFIFOSZ 0x1a /* 8-bit (see masks) */
-+#define MGC_O_HSFC_RXFIFOSZ 0x1b /* 8-bit (see masks) */
-+#define MGC_O_HSFC_TXFIFOADD 0x1c /* 16-bit offset shifted right 3 */
-+#define MGC_O_HSFC_RXFIFOADD 0x1e /* 16-bit offset shifted right 3 */
++ return result;
++}
+
-+/* Endpoint registers */
-+#define MGC_O_HSFC_TXMAXP 0x00
-+#define MGC_O_HSFC_TXCSR 0x02
-+#define MGC_O_HSFC_CSR0 MGC_O_HSFC_TXCSR /* re-used for EP0 */
-+#define MGC_O_HSFC_RXMAXP 0x04
-+#define MGC_O_HSFC_RXCSR 0x06
-+#define MGC_O_HSFC_RXCOUNT 0x08
-+#define MGC_O_HSFC_COUNT0 MGC_O_HSFC_RXCOUNT /* re-used for EP0 */
++static int atoi_from_user(const char* buffer, int count) {
++ char digits[8];
++ int len=min(count, 8);
++ copy_from_user(&digits, buffer, len);
++ return atoi(digits, 10, len);
++}
+
-+/*
-+ * MUSBHSFC Register bit masks
-+ */
+
-+/* POWER */
++static const char* decode_address(int index) {
++ static const char* COMMON_REGISTER_MAP[] = {
++ "FAddr", "Power", "IntrTx", "IntrRx",
++ "IntrTxE", "IntrRxE", "IntrUSB", "IntrUSBE",
++ "Frame", "Index","TestMode" };
++ return (index<11) ? COMMON_REGISTER_MAP[index]:NULL;
++}
++#endif
+
-+#define MGC_M_POWER_ISOUPDATE 0x80
-+#define MGC_M_POWER_SOFTCONN 0x40
-+#define MGC_M_POWER_HSENAB 0x20
-+#define MGC_M_POWER_HSMODE 0x10
-+#define MGC_M_POWER_RESET 0x08
-+#define MGC_M_POWER_RESUME 0x04
-+#define MGC_M_POWER_SUSPENDM 0x02
-+#define MGC_M_POWER_ENSUSPEND 0x01
++/* ----------------------------------------------------------------------- */
+
-+/* Interrupt register bit masks */
-+#define MGC_M_INTR_SUSPEND 0x01
-+#define MGC_M_INTR_RESUME 0x02
-+#define MGC_M_INTR_RESET 0x04
-+#define MGC_M_INTR_SOF 0x08
+
-+/* TESTMODE */
++/* Write to ProcFS
++ *
++ * C soft-connect
++ * c soft-disconnect
++ * I enable HS
++ * i disable HS
++ * R resume bus
++ * S start session (OTG-friendly when OTG-compiled)
++ * s stop session
++ * F force session (OTG-unfriendly)
++ * E rElinquish bus (OTG)
++ * H request host mode
++ * h cancel host request
++ * P disable the low-power mode that kills us in peripheral mode
++ * D<num> set/query the debug level
++ * Z zap
++ */
++static int MGC_ProcWrite(struct file *file, const char *buffer,
++ unsigned long count, void *data)
++{
++ char cmd;
++ uint8_t bReg;
++ uint8_t* pBase=((MGC_LinuxCd*)data)->pRegs;
+
-+#define MGC_M_TEST_FORCEFS 0x20
-+#define MGC_M_TEST_FORCEHS 0x10
-+#define MGC_M_TEST_PACKET 0x08
-+#define MGC_M_TEST_K 0x04
-+#define MGC_M_TEST_J 0x02
-+#define MGC_M_TEST_SE0_NAK 0x01
++ /* MOD_INC_USE_COUNT; */
++
++ if(copy_from_user(&cmd, buffer, 1) == 0){
++ switch(cmd) {
++ case 'C':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_SOFTCONN;
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++ }
++ break;
++
++ case 'c':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_SOFTCONN;
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++ }
++ break;
++
++ case 'I':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_HSENAB;
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++ }
++ break;
+
-+/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
-+#define MGC_M_FIFOSZ_DPB 0x10
-+/* allocation size (8, 16, 32, ... 4096) */
-+#define MGC_M_FIFOSZ_SIZE 0x0f
++ case 'i':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_HSENAB;
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++ }
++ break;
+
-+/* CSR0 */
++ case 'R':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg | MGC_M_POWER_RESUME);
++ WAIT_MS(10);
++ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++ WARN("Power Resumed\n");
++ } break;
+
-+#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
-+#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
-+#define MGC_M_CSR0_P_SENDSTALL 0x0020
-+#define MGC_M_CSR0_P_SETUPEND 0x0010
-+#define MGC_M_CSR0_P_DATAEND 0x0008
-+#define MGC_M_CSR0_P_SENTSTALL 0x0004
-+#define MGC_M_CSR0_TXPKTRDY 0x0002
-+#define MGC_M_CSR0_RXPKTRDY 0x0001
++ case 'S':
++ MGC_Session((MGC_LinuxCd*)data);
++ break;
+
-+/* TXCSR */
+
-+#define MGC_M_TXCSR_AUTOSET 0x8000
-+#define MGC_M_TXCSR_ISO 0x4000
-+#define MGC_M_TXCSR_MODE 0x2000
-+#define MGC_M_TXCSR_DMAENAB 0x1000
-+#define MGC_M_TXCSR_FRCDATATOG 0x0800
-+#define MGC_M_TXCSR_P_INCOMPTX 0x0080
-+#define MGC_M_TXCSR_CLRDATATOG 0x0040
-+#define MGC_M_TXCSR_P_SENTSTALL 0x0020
-+#define MGC_M_TXCSR_P_SENDSTALL 0x0010
-+#define MGC_M_TXCSR_FLUSHFIFO 0x0008
-+#define MGC_M_TXCSR_P_UNDERRUN 0x0004
-+#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
-+#define MGC_M_TXCSR_TXPKTRDY 0x0001
++ case 's':
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++ bReg &= ~MGC_M_DEVCTL_SESSION;
++ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++ break;
+
-+/* RXCSR */
++ case 'F':
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++ bReg |= MGC_M_DEVCTL_SESSION;
++ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++ break;
+
-+#define MGC_M_RXCSR_AUTOCLEAR 0x8000
-+#define MGC_M_RXCSR_P_ISO 0x4000
-+#define MGC_M_RXCSR_DMAENAB 0x2000
-+#define MGC_M_RXCSR_DISNYET 0x1000
-+#define MGC_M_RXCSR_DMAMODE 0x0800
-+#define MGC_M_RXCSR_INCOMPRX 0x0100
-+#define MGC_M_RXCSR_CLRDATATOG 0x0080
-+#define MGC_M_RXCSR_P_SENTSTALL 0x0040
-+#define MGC_M_RXCSR_P_SENDSTALL 0x0020
-+#define MGC_M_RXCSR_FLUSHFIFO 0x0010
-+#define MGC_M_RXCSR_DATAERR 0x0008
-+#define MGC_M_RXCSR_P_OVERRUN 0x0004
-+#define MGC_M_RXCSR_FIFOFULL 0x0002
-+#define MGC_M_RXCSR_RXPKTRDY 0x0001
++ case 'H':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++ bReg |= MGC_M_DEVCTL_HR;
++ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++ }
++ break;
+
-+/*
-+ * register access macros
-+ */
++ case 'h':
++ if ( pBase ) {
++ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++ bReg &= ~MGC_M_DEVCTL_HR;
++ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++ }
++ break;
+
-+/* Get offset for a given FIFO */
-+#define MGC_FIFO_OFFSET(_bEnd) (MGC_M_FIFO_EP0 + (_bEnd * 4))
++ /* Xap the controller */
++ case 'Z':
++ MGC_Zap((MGC_LinuxCd*)data);
++ break;
+
-+#endif /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c
---- linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c 2008-08-08 19:15:27.000000000 +0530
-@@ -0,0 +1,321 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_ioctl.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <asm/uaccess.h>
-+#include <linux/kernel.h>
++#if (MUSB_DEBUG>0)
++ /* read & write registers */
++ case 'r':
++ case 'w': {
++ uint8_t index=0;
++ uint32_t value=0;
++ char command[64];
+
-+#include <linux/usb.h>
++ memset(command, 0, sizeof(command));
++ copy_from_user(command, buffer, min(count, (unsigned long)63));
+
-+#include "musbdefs.h"
-+#include "musb_host.h"
++ /* detrermine the index,
++ * only the adrress now */
++ index=atoi(&command[2], 16, count-2);
++ if ( index>0 && pBase ) {
++ const char *address=decode_address(index);
+
-+#ifdef MUSB_DEBUG
-+extern int mgc_slow_device_kludge_delay;
-+#endif
++ if ( buffer[0]=='r' ) {
++ value=(command[1]=='8')
++ ? MGC_Read8(pBase, index)
++ : (command[1]=='f')
++ ? MGC_Read16(pBase, index)
++ : 0;
++ } else {
++ /* not write, not yet... */
++ index=-1;
++ }
+
-+/**
-+ * Zap the driver (warm start)
-+ * @param pThis the controller
-+ */
-+void MGC_Zap(MGC_LinuxCd* pThis) {
++ if ( address ) {
++ INFO("%s=0x%x\n", address, value);
++ } else {
++ INFO("0x%x=0x%x\n", index, value);
++ }
++ }
++ } break;
+
-+#ifdef MUSB_PARANOID
-+ if ( !pThis ) {
-+ ERR("Controller not initialized\n");
-+ return;
-+ }
-+#endif
++ /* set/read debug level */
++ case 'D': {
++ if ( count>1 ) {
++ int level=0;
++ level=atoi_from_user(&buffer[1], count-1);
++ MGC_SetDebugLevel(level);
++ } else {
++ INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel);
++ /* & dump the status to syslog */
++ }
++ } break;
+
-+ MGC_HdrcStop(pThis);
++ /* display queue status */
++ case 'Q': {
++ int index=-1;
++ char endb[256];
++ MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
+
-+#ifdef MUSB_VIRTHUB
-+ MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
-+ pThis->pRootDevice = NULL;
-+ mgc_hcd_flush(pThis);
-+#endif
-+
-+ WARN("Controller Stopped\n");
++ if (count>2) {
++ index=atoi_from_user(&buffer[1], count-1);
++ }
+
++ if ( dump_header_stats(pThis, endb)>0 ) {
++ printk(KERN_INFO"%s", endb);
++ }
+
+#ifdef MUSB_HOST
-+ MGC_InitLocalEndPoints(pThis);
-+#endif
++ if( MUSB_IS_HST(pThis) ) {
++ if ( index<0 ) {
++ uint8_t bEnd;
+
-+#ifdef MUSB_GADGET
++ /* generate the report for the end points */
++ for (bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++ if ( dump_end_stats(pThis, bEnd, endb)>0 ) {
++ printk(KERN_INFO"%s", endb);
++ }
++ }
+
++ } else {
++ if ( dump_end_stats(pThis, index, endb)>0 ) {
++ printk(KERN_INFO"%s", endb);
++ }
++ }
++ }
+#endif
+
-+ WAIT_MS(1000);
-+ MGC_HdrcStart( pThis );
-+ WARN("Controller Restarted\n");
-+}
+
-+/**
-+ * Start a session. Depeing on the controller mode (cable end) it will
-+ * pwer VBUS/initiate SRP and/or it will behave like a gadget.
-+ * @param pThis the controller
-+ *
-+ */
-+void MGC_Session(MGC_LinuxCd* pThis) {
-+ uint8_t bReg, sesn=0;
-+
-+#ifdef MUSB_PARANOID
-+ if ( !pThis ) {
-+ ERR("Controller not initialized\n");
-+ return;
-+ }
-+#endif
-+
-+ if ( MUSB_IS_ERR(pThis) ) {
-+ WARN("Error mode, zap the driver first\n");
-+ }
++ } break;
+
++ case 'd': {
++ if ( count>1 ) {
++ int delay=atoi_from_user(&buffer[1], count-1);
++ MGC_SetDeviceDelay(delay);
++ }
++ INFO("mgc_slow_device_kludge_delay=%d\n",
++ MGC_SetDeviceDelay(-1));
++ } break;
+
-+ if ( sesn ) {
-+ ERR("A %s session is active; terminate it first\n",
-+ MUSB_MODE(pThis));
-+ return;
++ /* flush */
++ case '?':
++ INFO("?: you are seeing it\n");
++ INFO("C/c: soft connect enable/disable\n");
++ INFO("I/i: hispeed enable/disable\n");
++ INFO("S/s: session set/clear\n");
++ INFO("F: \n");
++ INFO("H: host mode\n");
++ INFO("r/w: read write register\n");
++ INFO("Z: zap\n");
++ INFO("D: set/read dbug level\n");
++ INFO("Q: show queue status\n");
++ break;
++#endif
++
++ default:
++ ERR("Command %c not implemented\n", cmd);
++ break;
++ }
+ }
-+
+
-+ /* WHY!?!?! this looks like a race condition to me */
-+ bReg = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL);
-+ MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, bReg | MGC_M_DEVCTL_SESSION);
++ return count;
+}
+
+
+/**
-+ * Change the debug level.
-+ * @param level the new level
-+ */
-+void MGC_SetDebugLevel(int level) {
-+#if MUSB_DEBUG > 0
-+ MGC_DebugLevel=level;
-+ INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel);
-+#endif
-+}
-+
-+/**
-+ * Change the slow device delay.
-+ * @param delay the new delay
++ * Read from /proc filesystem.
++ * @param
++ * @param
++ * @param
++ * @param
++ * @param
++ * @param
+ */
-+int MGC_SetDeviceDelay(int delay) {
-+ if ( delay>0 ) {
-+ mgc_slow_device_kludge_delay=delay;
-+ }
-+ return mgc_slow_device_kludge_delay;
-+}
++static int MGC_ProcRead(char *page, char **start,
++ off_t off, int count, int *eof, void *data)
++{
++ off_t len=0;
++ char *buffer;
++ int rc=0, code=0;
++ unsigned long flags;
++ MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
+
-+/** Dump the current status and compile options.
-+ * @param pThis the device driver instance
-+ * @param buffer where to dump the status; it must be big enough hold the
-+ * result otherwise "BAD THINGS HAPPENS(TM)".
-+ */
-+int dump_header_stats(MGC_LinuxCd* pThis, char *buffer) {
-+ int code, count=0;
-+ const uint8_t* pBase=pThis->pRegs;
-+
-+ *buffer=0;
++ spin_lock_irqsave(&pThis->Lock, flags);
+
-+ code=sprintf(&buffer[count],
-+ "Compile Options: [debug=%d][dma=%s][gadget=%s][otg=%s][eps=%d]\n",
-+#if MUSB_DEBUG>0
-+ MGC_DebugLevel
-+#else
-+ -1
-+#endif
-+ ,
-+#ifdef MUSB_DMA
-+ "yes"
-+#else
-+ "no"
-+#endif
-+ ,
-+#ifdef MUSB_GADGET
-+ "yes"
-+#else
-+ "no"
-+#endif
-+ ,
-+#ifdef MUSB_OTG
-+ "yes"
-+#else
-+ "no"
-+#endif
-+ ,pThis->bEndCount);
-+ if ( code<0 ) {
-+ ERR("A problem generating the report\n");
-+ return count;
-+ } else {
-+ count+=code;
++ buffer=kmalloc(4*1024, GFP_USER);
++ if ( !buffer ) {
++ ERR("Out of memory\n");
++ return -1;
+ }
+
-+ code=sprintf(&buffer[count],
-+ "Current Status: %sDRC, Mode=%s (%s=%d) (Power=%02x, DevCtl=%02x)\n",
-+ ( pThis->bIsMultipoint ? "MH" : "H"),
-+ MUSB_MODE(pThis),
-+#ifdef MUSB_GADGET
-+ "address",
-+ (MUSB_IS_DEV(pThis)?pThis->bAddress:0,
-+#else
-+ "delay",
-+ mgc_slow_device_kludge_delay,
-+#endif
-+ MGC_Read8(pBase, MGC_O_HDRC_POWER),
-+ MGC_Read8(pBase, MGC_O_HDRC_DEVCTL));
-+ if ( code<0 ) {
-+ ERR("A problem generating the report\n");
-+ return count;
-+ } else {
-+ count+=code;
++ /* generate the report for the end points */
++ code=dump_header_stats(pThis, buffer);
++ if ( code>0 ) {
++ len+=code;
+ }
+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ {
-+ int i=0;
-+ mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
++#ifdef MUSB_HOST
++ if( MUSB_IS_HST(pThis) ) {
+
-+ code=sprintf(&buffer[count],
-+ "HCD: urb_queue_count=%d urb_exec_count=%d\n",
-+ pQueue->urb_queue_count, pQueue->urb_exec_count);
-+ if ( code<0 ) {
-+ ERR("A problem generating the report\n");
-+ return count;
-+ } else {
-+ count+=code;
-+ }
-+
-+ for (i=0; i<pThis->bEndCount; i++) {
-+ if ( !mgc_ep_is_idle( &pThis->aLocalEnd[i] ) ) {
-+ code=sprintf(&buffer[count], "ep%d, current=%p\n",
-+ i, MGC_GetCurrentUrb(&pThis->aLocalEnd[i]));
-+ if ( code<0 ) {
-+ ERR("A problem generating the report\n");
-+ return count;
-+ } else {
-+ count+=code;
-+ }
++ uint8_t bEnd;
++
++ for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++ code=dump_end_stats(pThis, bEnd, &buffer[len]);
++ if ( code>0 ) {
++ len+=code;
+ }
+ }
+ }
+#endif
-+
-+ return count;
++
++ if ( off<len ) {
++ int i=0, togo=len-off;
++ char *s=&buffer[off],*d=page;
++
++ if ( togo>count ) {
++ togo=count;
++ }
++
++ while ( i++<togo ) {
++ *d++=*s++;
++ }
++
++ rc=togo;
++ } else {
++ *buffer=0;
++ *eof=1;
++ }
++
++ kfree(buffer);
++ spin_unlock_irqrestore(&pThis->Lock, flags);
++ return rc;
+}
+
+
+/**
-+ * decode (convert to a name) the protocol used on an endpoint.
-+ * @param pThis the controller
-+ * @param bEnd the endpoint
++ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
++ * @param data the controller instance
+ */
-+static char* decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
-+ char* pProto = "Err ";
-+
-+ if ( MUSB_IS_DEV(pThis) ) {
-+#ifdef MUSB_GAGDET
-+ pProto=decode_dev_ep_protocol(pThis, bEnd);
-+#endif
-+ } else if ( MUSB_IS_HST(pThis) ) {
-+#ifdef MUSB_HOST
-+ pProto=decode_hst_ep_protocol(pThis, bEnd);
-+#endif
-+ }
-+
-+ return pProto;
++void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data) {
++ remove_proc_entry(data->pProcEntry->name, NULL);
+}
+
-+#ifdef MUSB_HOST
++/**
++ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
++ * @param data the controller instance
++ */
++void MGC_LinuxRemoveProcFs(MGC_LinuxCd* data) {
++ remove_proc_entry(data->pProcEntry->name, NULL);
++}
+
+/**
-+ * Dump statistics for a local end (driver operaiting in host mode).
-+ * @param pThis the device driver instance
-+ * @param bEnd
-+ * @param aBuffer the buffer to print the report to
++ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
++ * @param name
++ * @param data the controller instance
+ */
-+int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer) {
-+ int code, count=0;
-+ MGC_LinuxLocalEnd* pEnd=&pThis->aLocalEnd[bEnd];
++struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, MGC_LinuxCd* data) {
++ if ( !name ) {
++ name=data->aName;
++ }
+
-+ spin_lock(&pEnd->Lock);
++ data->pProcEntry=create_proc_entry(name,
++ S_IFREG | S_IRUGO | S_IWUSR, NULL);
++ if( data->pProcEntry )
++ {
++ data->pProcEntry->data = data;
++#ifdef MUSB_V26
++ data->pProcEntry->owner=THIS_MODULE;
++#endif
+
-+ do {
-+
-+ if ( mgc_ep_is_idle(pEnd) ) {
-+ code=snprintf(aBuffer, 256-count,
-+ "End-%01x: Idle (%s, proto=%s, pktsize=%04x, address=%02x, end=%02x\n",
-+ bEnd, ( pEnd->bIsTx ? "Tx" : "Rx" ), decode_protocol(pThis, bEnd),
-+ pEnd->wPacketSize, pEnd->bRemoteAddress, pEnd->bRemoteEnd);
-+ } else {
-+ code=snprintf(aBuffer, 256-count,
-+ "End-%01x: %s (urb=%p), %s, proto=%s, pkt size=%04x, address=%02x, end=%02x\n",
-+ bEnd, "Busy", MGC_GetCurrentUrb(pEnd),
-+ ( pEnd->bIsTx ? "Tx" : "Rx" ),
-+ decode_protocol(pThis, bEnd),
-+ pEnd->wPacketSize,
-+ pEnd->bRemoteAddress,
-+ pEnd->bRemoteEnd);
-+ }
-+
-+ if ( code<0 ) {
-+ break;
-+ } else {
-+ count+=code;
-+ }
-+
-+ if ( MUSB_IS_HST(pThis) ) {
-+ code = snprintf(&aBuffer[count], 256-count,
-+ " %10ld bytes Rx in %10ld pkts; %10ld errs, %10ld overruns\n",
-+ pEnd->dwTotalRxBytes,
-+ pEnd->dwTotalRxPackets,
-+ pEnd->dwErrorRxPackets,
-+ pEnd->dwMissedRxPackets);
-+ if ( code<0 ) {
-+ break;
-+ } else {
-+ count+=code;
-+ }
-+
-+ code=snprintf(&aBuffer[count], 256-count,
-+ " %10ld bytes Tx in %10ld pkts; %10ld errs, %10ld underruns\n",
-+ pEnd->dwTotalTxBytes,
-+ pEnd->dwTotalTxPackets,
-+ pEnd->dwErrorTxPackets,
-+ pEnd->dwMissedTxPackets);
-+ if ( code<0 ) {
-+ break;
-+ } else {
-+ count+=code;
-+ }
-+ } else {
-+ /* no stats for gadget, yet! */
-+ }
-+ } while(0);
++ data->pProcEntry->read_proc = MGC_ProcRead;
++ data->pProcEntry->write_proc = MGC_ProcWrite;
+
-+ spin_unlock(&pEnd->Lock);
-+ if ( code<0 ) {
-+ ERR("An error generating the report");
-+ return code;
-+ }
-+
-+ return count;
-+}
-+#endif
++ data->pProcEntry->size = 0;
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h
---- linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h 2008-07-28 15:21:00.000000000 +0530
-@@ -0,0 +1,32 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_ioctl.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
++ dbg("Registered /proc/%s\n", name);
++ } else {
++ dbg ("Cannot create a valid proc file entry");
++ }
+
-+#include "musbdefs.h"
-+
-+void MGC_Zap(MGC_LinuxCd* pThis);
-+void MGC_Session(MGC_LinuxCd* pThis);
-+void MGC_SetDebugLevel(int level);
-+int MGC_SetDeviceDelay(int delay);
-+int dump_header_stats(MGC_LinuxCd* pThis, char *buffer);
-+char*decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
-+#ifdef MUSB_HOST
-+int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
-+#endif
++ return data->pProcEntry;
++}
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c
---- linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c 2008-09-17 13:23:34.000000000 +0530
-@@ -0,0 +1,2306 @@
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_virthub.c
+@@ -0,0 +1,840 @@
+/*
-+ * linux/drivers/usb/nomadik/musb_plat_uds.c
++ * linux/drivers/usb/nomadik/musb_virthub.c
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+/*
-+ * Introduction.
-+ * The ICD works like the other Linux HCDs/Gadgets: it is threadless,
-+ * so it does everything either in response to an interrupt,
-+ * or during a call from an upper layer.
-+ * It implements a virtual root hub, so as to make uniform use
-+ * of the Linux hub driver.Linux
-+
-+ *
-+ * The Linux (host-side) USB core has no concept of binding (the authors
-+ * apparently missed the point of the pipe discussion in the USB spec).
-+ * Instead, class drivers simply submit URBs, and an HCD may reject
-+ * or defer them if sufficient resources are not available.
-+ * This means class drivers have no way to know if their requirements
-+ * can possibly be fulfilled, and may be blocked indefinitely by others,
-+ * without the end-user knowing why.
-+ * Therefore, whether things will work depends on the order of URB submissions
-+ * (which is dictated by the order of device insertion and/or driver loading
-+ * and thread scheduling).
-+ *
-+ * The URB encodes pipe information in an integer,
-+ * requiring table searches (hurting performance).
-+ *
-+ * For the HDRC, local endpoint 0 is the only choice for control traffic,
-+ * so it is reprogrammed as needed, and locked during transfers.
-+ * Bulk transfers are queued to the available local endpoint with
-+ * the smallest possible FIFO in the given direction
-+ * that will accomodate the transactions.
-+ *
-+ * A typical response to the completion of a periodic URB is immediate
-+ * submission of another one, so the HCD does not assume it can reprogram
-+ * a local periodic-targetted endpoint for another purpose.
-+ * Instead, submission of a periodic URB is taken as a permanent situation,
-+ * so that endpoint is untouched.
-+ * One could imagine reprogramming periodic endpoints for other uses
-+ * between their polling intervals, effectively interleaving traffic on them.
-+ * Unfortunately, this assumes no device would ever NAK periodic tokens.
-+ * This is because the core no notification to software when an attempted
-+ * periodic transaction is NAKed (its NAKlimit feature is only for
-+ * control/bulk).
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+/*
-+ * Optional macros:
-+ *
-+ * MUSB_FLAT_REG if defined, use the core's flag register model
-+ *
-+ * MUSB_DEBUG 0 => absolutely no diagnostics
-+ * 1 => minimal diagnostics (basic operational states)
-+ * 2 => 1 + detailed debugging of interface with USB core
-+ * 3 => 2 + internal debugging (e.g. every register write)
-+ * 4 => 3 + shared-IRQ-related checking
-+ *
-+ * MUSB_DMA if defined, include DMA support.
-+ * The DMA code to use is included below,
-+ * so may need to be edited if a non-Inventra DMA
-+ * controller is used with the Inventra core.
-+ *
-+ * MUSB_AHB_ID if defined, the core's identity is read from offset 0x400
-+ * to verify that the expected core is present
-+ *
-+ * MUSB_CONFIG_PROC_FS enables statistics/state info in /proc/musbhdrc<n>
-+ * where 0 <= n < number of instances of driver
-+ *
-+ *
-+ * MUSB_HARD_IRQ try SA_INTERRUPT first when acquiring the irq (fallback to
-+ * SA_SHIRQ when that fails.
-+ *
-+ *
-+ * Options taken from linux/config.h:
-+ * CONFIG_PM enables power-management
-+ */
+
++//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
++#include <linux/errno.h>
+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/usb.h>
++#include <linux/time.h>
++#include <linux/timer.h>
+
-+#include <asm/uaccess.h>
++#include <linux/usb.h>
+
-+#ifdef CONFIG_USB_DEBUG
-+#define DEBUG
++#ifndef MUSB_LINUX_MV21
++#include "../core/hcd.h"
++#define HAS_USB_TT_MULTI
+#else
-+#undef DEBUG
++#include <hub.h>
+#endif
+
-+
+#include "musbdefs.h"
-+#include "musb_host.h"
-+#include "../core/hcd.h"
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/i2c.h>
-+/********************** RETURN TYPES FOR IRQ ********************************/
-+
-+#ifdef MUSB_V26
-+#define RETURN_IRQ_HANDLED return(IRQ_HANDLED)
-+#define RETURN_IRQ_NONE return(IRQ_NONE)
-+#endif
-+
-+#ifdef MUSB_V24
-+typedef void irqreturn_t;
-+#define RETURN_IRQ_HANDLED return
-+#define RETURN_IRQ_NONE return
-+#endif
-+
-+
-+/* define this on command line */
-+#ifndef MUSB_DEFAULT_IRQTYPE
-+#define MUSB_DEFAULT_IRQTYPE SA_SHIRQ
-+#endif
-+
-+/****************************** CONSTANTS ********************************/
-+
-+#define DRIVER_AUTHOR "STMicroelectronics"
-+#define DRIVER_DESC "Nomadik USB Driver"
-+
-+#ifndef MUSB_VERSION
-+#define MUSB_VERSION "x.x"
-+#endif
-+
-+#define DRIVER_INFO DRIVER_DESC "v" MUSB_VERSION
-+#define DRIVER_NAME "HCD_NAME"
-+
-+static const char longname[] = DRIVER_INFO;
-+static const char shortname[] = DRIVER_NAME;
-+
-+/* this module is always GPL, the gadget might not... */
-+MODULE_DESCRIPTION (DRIVER_INFO);
-+MODULE_AUTHOR (DRIVER_AUTHOR);
-+MODULE_LICENSE ("GPL");
-+
-+/* time (millseconds) to wait before a restart */
-+#define MUSB_RESTART_TIME 5000
-+/* how many babbles to allow before giving up */
-+#define MUSB_MAX_BABBLE_COUNT 10
-+/* how many buss errors before stopping the operations */
-+#define MUSB_MAX_VBUS_ERRORS 3
-+
-+/* WEIRD KLUDGE! */
-+#define IS_INVALID_ADDRESS(_x) (((unsigned long)_x)<(unsigned long)1024)
-+
-+#define A_IDLE 1
-+#define B_IDLE 2
-+#define PERIPHERAL 3
-+#define HOST 4
-+
-+#define MAJOR_NUMBER_OTG 0x0
-+#define OTG_DEEP_SLEEP 0x1
-+#define OTG_WAKEUP 0x2
-+#define SRP_TEST 0x3
-+#define HNP_TEST 0x4
-+#define PRINT_REG 0x5
-+#define HOST_A_IDLE 0x6
-+#define OTG_SUSPEND 0x7
-+#define OTG_RESUME 0x8
-+
-+#define SUSPEND 0x0
-+#define RESUME 0x1
-+
+
+/******************************* FORWARDS ********************************/
-+MGC_LinuxCd *udc_address;
-+struct usb_hcd *hcd1;
-+int udcinitmonitorflag_isr=0,udcinitmonitorflag_init=0;
-+extern void driver_change_mode_handler(uint8_t role);
-+void otg_disconnect(MGC_LinuxCd *pThis);
-+int dev_safe_remove=0;
-+extern int Urb_status;
-+struct urb *Urb_struct;
-+uint8_t temp;
-+uint8_t b_hnp_suspend=0;
-+uint8_t b_hnp_init=0;
-+void del_timer_func(void);
-+extern int udc_setup(void);
-+extern void udc_reset(void);
-+extern void udc_resume(void);
-+extern void udc_suspend(void);
-+extern void udc_intr_disable(void);
-+extern uint8_t host_a_idle;
-+static void funct_host_notify_timer(unsigned long pThis);
-+static struct timer_list notify_timer;
-+extern int nomadik_udc_init(MGC_LinuxCd *pThis);
-+extern void musb_reset_isr(void);
-+extern void udc_disconnect_isr(void);
-+extern uint8_t udc_ep0_irq(void);
-+extern void udc_ep_tx_irq(uint8_t bEnd) ;
-+extern void udc_ep_rx_irq(uint8_t bEnd) ;
-+
-+#ifndef MUSB_USE_HCD_DRIVER
-+#ifdef MUSB_VIRTHUB
-+#ifndef MUSB_V26_POST10
-+/* Linux USBD glue */
-+STATIC int mgc_linux_alloc_device(struct usb_device* pDevice);
-+STATIC int mgc_linux_free_device(struct usb_device* pDevice);
-+#endif
-+STATIC int MGC_LinuxGetFrameNumber(struct usb_device* pDevice);
-+#endif
-+#endif
-+
-+STATIC void mgc_reset(MGC_LinuxCd* pThis);
-+uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData);
-+/* Interrupt service routine */
-+#ifndef MUSB_USE_HCD_DRIVER
-+STATIC irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r);
-+#endif
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+void mgc_hcd_flush(MGC_LinuxCd* pThis);
-+#endif
-+
-+/* HDRC functions */
-+STATIC void MGC_HdrcDropResume(unsigned long pParam);
-+STATIC void MGC_HdrcRestart(unsigned long pParam);
-+
-+STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis);
-+
-+#ifdef MUSB_V26
-+void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
-+ unsigned iMemFlags, dma_addr_t* pDmaAddress);
-+void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
-+ void* address, dma_addr_t DmaAddress);
-+#endif
+
-+STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis);
++static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub,
++ void (*pfExpired)(unsigned long), unsigned long timeout);
++static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb);
++static void MGC_VirtualHubTimerExpired(unsigned long ptr);
+
-+#ifdef MUSB_V26_POST10
-+struct usb_bus;
-+int MGC_LinuxHubSuspend(struct usb_bus *pBus);
-+int MGC_LinuxHubResume(struct usb_bus *pBus);
-+#endif
++/******************************* GLOBALS *********************************/
+
-+#ifdef MUSB_V26
-+void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress);
-+#endif
++/** device descriptor */
++static uint8_t MGC_aVirtualHubDeviceDesc[] =
++{
++ USB_DT_DEVICE_SIZE,
++ USB_DT_DEVICE,
++ 0x00, 0x02, /* bcdUSB */
++ USB_CLASS_HUB, /* bDeviceClass */
++ 0, /* bDeviceSubClass */
++ 1, /* bDeviceProtocol (single TT) */
++ 64, /* bMaxPacketSize0 */
++ 0xd6, 0x4, /* idVendor */
++ 0, 0, /* idProduct */
++ 0, 0, /* bcdDevice */
++ 0, /* iManufacturer */
++ 0, /* iProduct */
++ 0, /* iSerialNumber */
++ 1 /* bNumConfigurations */
++};
+
++/** device qualifier */
++static uint8_t MGC_aVirtualHubQualifierDesc[] =
++{
++ USB_DT_DEVICE_QUALIFIER_SIZE,
++ USB_DT_DEVICE_QUALIFIER,
++ 0x00, 0x02, /* bcdUSB */
++ USB_CLASS_HUB, /* bDeviceClass */
++ 0, /* bDeviceSubClass */
++ 0, /* bDeviceProtocol */
++ 64, /* bMaxPacketSize0 */
++ 0xd6, 0x4, /* idVendor */
++ 0, 0, /* idProduct */
++ 0, 0, /* bcdDevice */
++ 0, /* iManufacturer */
++ 0, /* iProduct */
++ 0, /* iSerialNumber */
++ 1 /* bNumConfigurations */
++};
+
-+/******************************* GLOBALS *********************************/
++/** Configuration descriptor */
++static uint8_t MGC_VirtualHubConfigDesc[] =
++{
++ USB_DT_CONFIG_SIZE,
++ USB_DT_CONFIG,
++ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
++ 0x01, /* bNumInterfaces */
++ 0x01, /* bConfigurationValue */
++ 0x00, /* iConfiguration */
++ 0xE0, /* bmAttributes (self-powered, remote wake) */
++ 0x00, /* MaxPower */
+
++ /* interface */
++ USB_DT_INTERFACE_SIZE,
++ USB_DT_INTERFACE,
++ 0x00, /* bInterfaceNumber */
++ 0x00, /* bAlternateSetting */
++ 0x01, /* bNumEndpoints */
++ USB_CLASS_HUB, /* bInterfaceClass */
++ 0x00, /* bInterfaceSubClass */
++ 0x00, /* bInterfaceProtocol */
++ 0x00, /* iInterface */
+
-+MGC_LinuxCd *hcd_to_musbstruct(void *ptr)
-+{
-+#ifdef MUSB_USE_HCD_DRIVER
-+ return (MGC_LinuxCd*)((struct usb_hcd *)ptr)->hcd_priv;
-+#else
-+ return (MGC_LinuxCd*)ptr;
-+#endif
-+}
++ /* endpoint */
++ USB_DT_ENDPOINT_SIZE,
++ USB_DT_ENDPOINT,
++ USB_DIR_IN | 1, /* bEndpointAddress: IN Endpoint 1 */
++ USB_ENDPOINT_XFER_INT, /* bmAttributes: Interrupt */
++ (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0, /* wMaxPacketSize */
++ 12 /* bInterval: 256 ms */
++};
+
-+struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis)
++/** other-speed Configuration descriptor */
++static uint8_t MGC_VirtualHubOtherConfigDesc[] =
+{
-+#ifdef MUSB_USE_HCD_DRIVER
-+ return container_of((void*)pThis, struct usb_hcd, hcd_priv);
-+#else
-+ return NULL;
-+#endif
-+}
++ USB_DT_CONFIG_SIZE,
++ USB_DT_OTHER_SPEED,
++ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
++ 0x01, /* bNumInterfaces */
++ 0x01, /* bConfigurationValue */
++ 0x00, /* iConfiguration */
++ 0xE0, /* bmAttributes (self-powered, remote wake) */
++ 0x00, /* MaxPower */
+
-+/******************************* GLOBALS *********************************/
++ /* interface */
++ USB_DT_INTERFACE_SIZE,
++ USB_DT_INTERFACE,
++ 0x00, /* bInterfaceNumber */
++ 0x00, /* bAlternateSetting */
++ 0x01, /* bNumEndpoints */
++ USB_CLASS_HUB, /* bInterfaceClass */
++ 0x00, /* bInterfaceSubClass */
++ 0x00, /* bInterfaceProtocol */
++ 0x00, /* iInterface */
+
-+unsigned int MGC_nIndex = 0;
++ /* endpoint */
++ USB_DT_ENDPOINT_SIZE,
++ USB_DT_ENDPOINT,
++ USB_DIR_IN | 1, /* bEndpointAddress: IN Endpoint 1 */
++ USB_ENDPOINT_XFER_INT, /* bmAttributes: Interrupt */
++ (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0, /* wMaxPacketSize */
++ 0xff /* bInterval: 255 ms */
++};
+
-+static const char MGC_HcdName [] = "musb-hcd";
++/****************************** FUNCTIONS ********************************/
+
-+#ifndef MUSB_USE_HCD_DRIVER
+/**
-+ * Virtual hub functions: Linux USBD calls these
++ * Generic timer activation helper. Requires the hub structure to
++ * be locked.
++ *
++ * @param pHub pointer to hub struct
++ * @param pfExpired callback function
++ * @param timeout millisecs
++ * @requires spin_lock(pHub->Lock)
+ */
-+#ifdef MUSB_VIRTHUB
-+static struct usb_operations MGC_LinuxOperations =
++static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub,
++ void (*pfExpired)(unsigned long), unsigned long timeout)
+{
-+#ifndef MUSB_V26_POST10
-+ .allocate = mgc_linux_alloc_device,
-+ .deallocate = mgc_linux_free_device,
-+#endif
-+
-+ .get_frame_number = MGC_LinuxGetFrameNumber,
-+
-+#ifdef MUSB_V24
-+ .submit_urb = MGC_LinuxSubmitUrb24,
-+#endif
-+
-+#ifdef MUSB_V26
-+ .submit_urb = MGC_LinuxSubmitUrb26,
-+#endif
++ DBG(2, "<== pHub=%p, pHub->pUrb=%p\n", pHub, pHub->pUrb);
++ del_timer(&pHub->Timer); /* make sure another timer is not running */
++ init_timer(&(pHub->Timer));
++ pHub->Timer.function = pfExpired;
++ pHub->Timer.data = (unsigned long)pHub;
++ pHub->Timer.expires = jiffies + timeout * HZ / 1000;
++ add_timer( &(pHub->Timer) );
++}
+
-+#ifdef MUSB_V24
-+ .unlink_urb = MGC_LinuxUnlinkUrb24,
-+#endif
-+#ifdef MUSB_V26
-+ .unlink_urb = MGC_LinuxUnlinkUrb26,
-+#endif
++/**
++ * Report the VHUB status bits. Assumes that pData has enough
++ * storage for all of them.
++ * @param pHub the hub
++ * @param pData the data buffer status shoudl be written to
++ * @return
++ */
++int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData) {
++ int nPort, length=1;
++ uint8_t bData=0, bBit=1;
+
-+#ifdef MUSB_V26
-+ .buffer_alloc = MGC_LinuxBufferAlloc,
-+ .buffer_free = MGC_LinuxBufferFree,
-+ .disable = mgc_linux_disable,
-+#endif
++ /* count 1..N to accomodate hub status bit */
++ for(nPort = 1; nPort <= pHub->bPortCount + 1; nPort++) {
++ if(pHub->aPortStatusChange[nPort-1].wChange & 1) {
++ bData |= 1 << bBit;
++ }
+
-+#ifdef MUSB_V26_POST10
-+ .hub_suspend = MGC_LinuxHubSuspend,
-+ .hub_resume = MGC_LinuxHubResume,
-+#endif
-+};
-+#endif
-+#endif
++ if(++bBit > 7) {
++ *pData++ = bData;
++ bData = bBit = 0;
++ length++;
++ }
++ }
+
-+const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE] = {
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
-+ 0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf,
-+ 0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf,
-+ 0xef, 0xf7, 0xfb, 0xfd, 0x7e
-+};
++ if(bBit) {
++ *pData++ = bData;
++ }
+
++ return length;
++}
+
++/*
++ * assumes pHub to be locked!
++ * @requires spin_lock(pHub->Lock)
++ */
++static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb)
++{
++ pHub->bIsChanged = FALSE;
+
-+int otg_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
-+int otg_open (struct inode *inode, struct file *file);
-+int otg_close (struct inode *inode, struct file *file);
-+extern void otg_deep_sleep(void);
-+extern void otg_wakeup(void);
-+extern void set_host_a_idle(void);
-+extern void hnp_initiate(void);
-+extern void srp_initiate(void);
++ pUrb->actual_length=mgc_rh_port_status(pHub, (uint8_t*)pUrb->transfer_buffer);
++ if (pUrb->actual_length && pUrb->complete) {
++ COMPLETE_URB(pUrb, NULL);
++ }
++}
+
-+static struct file_operations otg_fops = {
-+ owner: THIS_MODULE,
-+ read: NULL,
-+ write: NULL,
-+ ioctl: otg_ioctl,
-+ open: otg_open,
-+ flush: NULL,
-+ release: otg_close,
-+};
++/**
++ * Timer expiration function to complete the interrupt URB on changes
++ * @param ptr standard expiration param (hub pointer)
++ */
++static void MGC_VirtualHubTimerExpired(unsigned long ptr)
++{
++ struct urb* pUrb;
++ MGC_VirtualHub* pHub = (MGC_VirtualHub*)ptr;
+
++ DBG(2, "<== pHub=%p, pHub->pUrb=%p, pUrb->hcpriv=%p\n", pHub,
++ pHub->pUrb, (pHub->pUrb)?((struct urb*)pHub->pUrb)->hcpriv:NULL);
+
-+/******************************* GLOBALS *********************************/
++ spin_lock(&pHub->Lock);
++ pUrb=pHub->pUrb;
++ if(pUrb && (pUrb->hcpriv == pHub)) {
++ uint8_t bPort;
+
-+int otg_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ /* to prevent compiler warnings */
-+ inode=inode;
-+ filp=filp;
-+ arg=arg;
++ for(bPort = 0; bPort < pHub->bPortCount; bPort++) {
++ if ( pHub->aPortStatusChange[bPort].wChange ) {
++ pUrb->status=0;
++ MGC_VirtualHubCompleteIrq(pHub, pUrb);
++ break;
++ }
++ }
+
-+ switch(cmd) {
-+
-+ case OTG_DEEP_SLEEP:
-+ del_timer(¬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 <linux/spinlock.h>
++#include <linux/timer.h>
++#include <linux/version.h>
+
-+#ifndef MUSB_GADGET
-+ /* enable high-speed/low-power and start session & suspend IM host*/
-+ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
++#define USB_NEW_DEVICE(_vh) usb_register_root_hub((_vh)->pDevice, (_vh)->pBus->controller)
+#else
-+ {
-+ uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
-+ }
++#ifdef __bluecat__
++#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice, (((_vh)->pDevice)->parent)?&((_vh)->pDevice)->parent->dev:NULL )
++#else
++#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice)
++#endif
+#endif
+
-+}
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
++#define MUSB_REGISTER_ROOT_HUB
++#endif
++
++struct urb;
++struct usb_bus;
++
++#ifdef MUSB_USE_HCD_DRIVER
++struct usb_hcd;
++#endif
+
+/**
-+* Program the HDRC to stop (disable interrupts, etc.).
-+*/
-+void MGC_HdrcStop(MGC_LinuxCd* pThis)
-+{
-+ DBG(2, "<==\n");
++ * Introduction.
++ * For USB controllers lacking embedded root hubs,
++ * this module can be used as a virtual root hub,
++ * with one or more controllers as the virtual hub's ports.
++ */
+
-+ /* flush endpoints */
-+#ifdef MUSB_VIRTHUB
-+ {
-+ uint8_t bEnd;
-+
-+ mgc_hdrc_disable(pThis);
-+ for(bEnd = 0; bEnd < min(16, (int)pThis->bEndCount); bEnd++) {
-+ MGC_HdrcStopEnd(pThis, bEnd);
-+ }
-+ }
-+#endif
-+}
++/****************************** CONSTANTS ********************************/
+
-+/* ------------------------------------------------------------------------ */
++/** Maximum number of ports to accomodate */
++#define MGC_VIRTUALHUB_MAX_PORTS 7
+
-+#define MUSB_HDRC_ULPI_ACCESS
-+#ifdef MUSB_HDRC_ULPI_ACCESS
++/******************************** TYPES **********************************/
+
-+uint8_t MGC_HdrcUlpiVbusControl(MGC_LinuxCd* pThis, uint8_t bExtSource, uint8_t bExtIndicator)
-+{
-+ uint8_t bVal;
-+ uint8_t* pBase = pThis->pRegs;
-+
-+ /* ensure not powered down */
-+ if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
-+ return FALSE;
-+ }
++/**
++ * Set a port's power on or off.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bPower TRUE to power on the port; FALSE to power off
++ */
++typedef void (*MGC_pfSetPortPower)(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bPower);
+
-+ bVal = bExtSource ? MGC_M_ULPI_VBUSCTL_USEEXTVBUS : 0;
-+ bVal |= bExtIndicator ? MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND : 0;
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_VBUSCTL, bVal);
-+
-+ return TRUE;
-+}
++/**
++ * Enable or disable a port.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bEnable TRUE to enable port; FALSE to disable
++ */
++typedef void (*MGC_pfSetPortEnable)(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bEnable);
+
-+uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData)
-+{
-+ uint8_t bCtl = 0;
-+ uint8_t* pBase = pThis->pRegs;
++/**
++ * Set a port's suspend mode on or off.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bSuspend TRUE to suspend port; FALSE to resume
++ */
++typedef void (*MGC_pfSetPortSuspend)(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bSuspend);
+
-+ /* ensure not powered down */
-+ if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
-+ return FALSE;
-+ }
++/**
++ * Set a port's reset on or off.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bReset TRUE to assert reset on the bus behind a port; FALSE to deassert
++ */
++typedef void (*MGC_pfSetPortReset)(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bReset);
+
-+ /* polled */
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr);
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL,
-+ MGC_M_ULPI_REGCTL_READNOTWRITE | MGC_M_ULPI_REGCTL_REG);
-+
++/**
++ * MGC_PortServices.
++ * Services provided to a virtual by a USB port controller.
++ * @field pPrivateData port controller's implementation data;
++ * not to be interpreted by virtual hub
++ * @param pfSetPortPower set-port-power call
++ * @param pfSetPortEnable set-port-enable call
++ * @param pfSetPortSuspend set-port-suspend call
++ * @param pfSetPortReset set-port-reset call
++ */
++typedef struct
++{
++ void* pPrivateData;
++ MGC_pfSetPortPower pfSetPortPower;
++ MGC_pfSetPortEnable pfSetPortEnable;
++ MGC_pfSetPortSuspend pfSetPortSuspend;
++ MGC_pfSetPortReset pfSetPortReset;
++} MGC_PortServices;
+
-+ while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) {
-+ bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL);
-+ }
-+
-+ *pbData = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGDATA);
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
-+ return TRUE;
-+}
++/**
++ * MGC_HubPortStatusChange.
++ * @field wStatus status
++ * @field wChange change
++ */
++typedef struct
++{
++ uint16_t wStatus;
++ uint16_t wChange;
++} MGC_HubPortStatusChange;
+
-+uint8_t MGC_HdrcWriteUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t bData)
++/**
++ * MGC_VirtualHub.
++ * Virtual USB hub instance data.
++ * @field Lock spinlock
++ * @field pBus our bus pointer
++ * @field pDevice our device pointer
++ * @field pUrb pointer to interrupt URB for status change
++ * @field pPortServices pointer to port services
++ * @field Timer interval timer for status change interrupts
++ * @field aPortStatusChange status/change array
++ * @field bPortCount how many ports
++ * @field wInterval actual interval in milliseconds
++ * @field bIsChanged TRUE if changes to report
++ * @field bAddress address assigned by usbcore
++ */
++typedef struct
+{
-+ uint8_t bCtl = 0;
-+ uint8_t* pBase = pThis->pRegs;
++ spinlock_t Lock;
++ struct usb_bus* pBus;
++ struct usb_device* pDevice;
+
-+ /* ensure not powered down */
-+ if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
-+ return FALSE;
-+ }
++ void *pUrb;
++ MGC_PortServices* pPortServices;
++ struct timer_list Timer;
++ MGC_HubPortStatusChange aPortStatusChange[MGC_VIRTUALHUB_MAX_PORTS];
++ uint8_t bPortCount;
++ uint16_t wInterval;
++ uint8_t bIsChanged;
++ uint8_t bAddress;
+
-+ /* polled */
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr);
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGDATA, bData);
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, MGC_M_ULPI_REGCTL_REG);
++} MGC_VirtualHub;
+
-+ while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) {
-+ bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL);
-+ }
++/******************************** Protos **********************************/
+
-+ MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
++extern int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData);
+
-+ return TRUE;
-+}
-+#endif
++#ifdef MUSB_VIRTHUB
++void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bPower);
++void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bEnable);
++void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bSuspend);
++void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
++ uint8_t bReset);
++
++extern int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus,
++ uint8_t bPortCount, MGC_PortServices* pPortServices);
++extern void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub);
++extern void MGC_VirtualHubStart(MGC_VirtualHub* pHub);
++extern void MGC_VirtualHubStop(MGC_VirtualHub* pHub);
++extern int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
++extern int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
++extern void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex, uint8_t bHubSpeed);
++extern void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex, uint8_t bSpeed);
++extern void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex);
++extern void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex);
+
-+/* ------------------------------------------------------------------------ */
++#else /* #ifdef MUSB_VIRTHUB */
+
-+/**
-+* Discover HDRC configuration.
-+* @param wType
-+* @param pThis the controller instance
-+*/
-+STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis)
++static int uint8_t MGC_VirtualHubInit(MGC_VirtualHub* pHub,
++ struct usb_bus* pBus, uint8_t bPortCount,
++ MGC_PortServices* pPortServices)
+{
-+#ifdef MUSB_AHB_ID
-+ uint32_t dwData;
-+#endif
-+ uint8_t reg, bType=0;
-+ uint16_t wRelease, wRelMajor, wRelMinor;
-+ char aInfo[78], aRevision[32], aDate[12];
-+ void* pBase = pThis->pRegs;
-+
-+ DBG(2, "<==\n");
++ DBG(-1, "this should not be called");
++ return -ENODEV;
++};
++static inline void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub) {
++ DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubStart(MGC_VirtualHub* pHub) {
++ DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubStop(MGC_VirtualHub* pHub) {
++ DBG(-1, "this should not be called");
++};
++static inline int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb) {
++ DBG(-1, "this should not be called");
++ return -ENODEV;
++};
+
-+ /* log core options */
-+ MGC_SelectEnd(pBase, 0);
-+ reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_CONFIGDATA, 0);
++static inline int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb) {
++ DBG(-1, "this should not be called");
++ return -ENODEV;
++};
+
-+ strcpy(aInfo,(reg & MGC_M_CONFIGDATA_UTMIDW)?"UTMI-16":"UTMI-8");
-+ if(reg & MGC_M_CONFIGDATA_DYNFIFO) {
-+ strcat(aInfo, ", dyn FIFOs");
-+ }
-+ if(reg & MGC_M_CONFIGDATA_MPRXE) {
-+ strcat(aInfo, ", bulk combine");
-+ }
-+ if(reg & MGC_M_CONFIGDATA_MPTXE) {
-+ strcat(aInfo, ", bulk split");
-+ }
-+ if(reg & MGC_M_CONFIGDATA_HBRXE) {
-+ strcat(aInfo, ", HB-ISO Rx");
-+ }
-+ if(reg & MGC_M_CONFIGDATA_HBTXE) {
-+ strcat(aInfo, ", HB-ISO Tx");
-+ }
-+ if(reg & MGC_M_CONFIGDATA_SOFTCONE) {
-+ strcat(aInfo, ", SoftConn");
-+ }
-+
-+ INFO("ConfigData=0x%02x (%s)\n", reg, aInfo);
++static inline void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex, uint8_t bHubSpeed) {
++ DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex, uint8_t bSpeed) {
++ DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub,
++ uint8_t bPortIndex) {
++ DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub,
++uint8_t bPortIndex) {
++ DBG(-1, "this should not be called");
++};
+
-+#ifdef MUSB_AHB_ID
-+ dwData = MGC_Read32(pBase, 0x404);
-+ sprintf(aDate, "%04d-%02x-%02x", (dwData & 0xffff),
-+ (dwData >> 16) & 0xff,
-+ (dwData >> 24) & 0xff);
-+ dwData = MGC_Read32(pBase, 0x408);
-+ printk("ID2=%lx\n", (long unsigned)dwData);
-+ dwData = MGC_Read32(pBase, 0x40c);
-+ printk("ID3=%lx\n", (long unsigned)dwData);
-+ bType = MGC_Read8(pBase, 0x400);
-+ pThis->bIsMultipoint=('M' == bType)
-+ ? TRUE : FALSE;
-+#else
-+ bType = 'x';
-+ pThis->bIsMultipoint=(MUSB_CONTROLLER_MHDRC == wType)
-+ ? TRUE : FALSE;
+#endif
-+
-+ /* log release info */
-+ wRelease = MGC_Read16(pBase, 0x6c);
-+ wRelMajor = (wRelease >> 10) & 0x1f;
-+ wRelMinor = wRelease & 0x3ff;
-+ snprintf(aRevision, 32, "%d.%d%s", wRelMajor,
-+ wRelMinor, (wRelease & 0x8000) ? "RC" : "");
-+ INFO("%cDRC version %s %s\n", bType, aRevision, aDate);
+
+
-+ /* configure ep0 */
-+ pThis->aLocalEnd[0].wMaxPacketSizeTx = MGC_END0_FIFOSIZE;
-+ pThis->aLocalEnd[0].wMaxPacketSizeRx = MGC_END0_FIFOSIZE;
++#endif /* multiple inclusion protection */
+
-+ /* discover endpoint configuration */
-+ pThis->bBulkTxEnd = 0;
-+ pThis->bBulkRxEnd = 0;
-+ pThis->bEndCount = 1;
-+ pThis->wEndMask = 1;
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musbdefs.h
+@@ -0,0 +1,828 @@
++/*
++ * linux/drivers/usb/nomadik/musbdefs.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
+
-+#ifdef MUSB_C_DYNFIFO_DEF
-+ if(!(reg & MGC_M_CONFIGDATA_DYNFIFO)) {
-+ ERR("Dynamic FIFOs not detected in hardware; please rebuild software\n");
-+ return FALSE;
-+ }
-+#else
-+ if (reg & MGC_M_CONFIGDATA_DYNFIFO) {
-+ ERR("Dynamic FIFOs detected in hardware; please rebuild\n");
-+ return FALSE;
-+ }
-+#endif
++#ifndef __MUSB_MUSBDEFS_H__
++#define __MUSB_MUSBDEFS_H__
+
-+ MGC_HdrcConfigureEps(pThis);
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
+
-+#ifdef MUSB_HOST
-+ MGC_InitLocalEndPoints(pThis);
++#ifdef MUSB_CONFIG_PROC_FS
++#include <linux/fs.h>
+#endif
+
-+ /* claim the bulk tx/rx ends */
-+ if(pThis->bBulkTxEnd) {
-+ pThis->aLocalEnd[pThis->bBulkTxEnd].bIsClaimed = TRUE;
-+ }
++/* useful for compiling across linux version & debug definitions */
++#include "musb_cross.h"
++#include "debug.h"
+
-+ if(pThis->bBulkRxEnd) {
-+ pThis->aLocalEnd[pThis->bBulkRxEnd].bIsClaimed = TRUE;
-+ }
++/* Board-specific definitions (hard-wired controller locations/IRQs) */
++#include "plat_cnf.h"
++#include "plat_arc.h"
++#include "musbhdrc.h"
+
-+ return TRUE;
-+}
++/****************************** VERIFY THE DEFINES **************************
++ * determine how to compile the driver; MUSB_GADGET->as gadget driver,
++ * MUSB_HOST as host mode, MUSB_OTG -> otg mode (host and gadget)
++ *
++ * OTG => GADGET
++ */
+
-+/**************************************************************************
-+ * Linux HCD functions
-+**************************************************************************/
++#ifdef MUSB_GSTORAGE
+
-+#ifdef MUSB_V26
-+#define IS_TIMER_INITILIZED(_t) ((_t)->magic==TIMER_MAGIC)
-+#else
-+#define IS_TIMER_INITILIZED(_t) (1)
++/* for now */
++#ifndef MUSB_OTG
++#define MUSB_OTG
+#endif
+
-+/**
-+ * Generic timer creation.
-+ * @param pThis instance pointer
-+ * @param pfFunc timer fire callback
-+ * @param pParam parameter for callback
-+ * @param millisecs how many milliseconds to set
-+ */
-+void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long),
-+ unsigned long pParam, unsigned long millisecs)
-+{
-+ DBG(2, "<==\n");
-+
-+ init_timer(&(pThis->Timer));
-+ pThis->Timer.function = pfFunc;
-+ pThis->Timer.data = (unsigned long)pParam;
-+ pThis->Timer.expires = jiffies + (HZ * millisecs) / 1000;
-+ add_timer( &(pThis->Timer) );
-+}
-+
-+#ifdef MUSB_V26
-+void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
-+ unsigned iMemFlags, dma_addr_t* pDmaAddress)
-+{
-+ /* for now, just kmalloc it */
-+ MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv);
++#endif
+
-+#ifdef MUSB_PARANOID
-+ if ( !pThis ) {
-+ ERR("cannot find the controller, cannot allocate the memory\n");
-+ return 0;
-+ }
++#ifdef MUSB_OTG
++#endif
++#ifndef MUSB_HOST
++#define MUSB_HOST
+#endif
+
-+ DBG(2, "<== allocating memory on bus (%s), %d, pDmaAddress=%p\n",
-+ pBus->bus_name, pBus->busnum, pDmaAddress );
-+ return MGC_AllocBufferMemory(pThis, nSize, iMemFlags, pDmaAddress);
-+}
++#ifdef CONFIG_PROC_FS
++#ifndef MUSB_CONFIG_PROC_FS
++#define MUSB_CONFIG_PROC_FS
++#endif
++#endif
+
-+void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
-+ void* address, dma_addr_t dma)
-+{
-+ MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv);
++#ifdef MUSB_PROC_TESTMUSB
+
-+#ifdef MUSB_PARANOID
-+ if ( !pThis ) {
-+ KFREE(address);
-+ ERR("cannot find the controller, cannot free the memory properly\n");
-+ return;
-+ }
++#ifndef CONFIG_PROC_FS
++#error "TestMusb needs CONFIG_PROC_FS"
+#endif
+
-+ MGC_FreeBufferMemory(pThis, nSize, address, dma);
-+}
++#ifndef MUSB_HOST
++#error "TestMusb needs HOST MODE"
+#endif
+
++#endif
+
-+#if defined(MUSB_V26) || defined(MUSB_GADGET)
-+/**
-+ * Allocate memory for a buffer that might use DMA.
-+ *
-+ * @param pThis
-+ * @param bytes
-+ * @param gfp_flags
-+ * @param dma NULL when DMAble memeory is not requested.
-+ */
-+void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma) {
-+ void* addr = NULL;
-+
-+ if ( dma ) {
-+ *dma = DMA_ADDR_INVALID;
-+ }
-+
-+#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21)
-+ {
-+ KMALLOC(addr, bytes, gfp_flags);
-+ if ( addr && dma ) {
-+ *dma = virt_to_phys(addr);
-+ }
-+ DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma);
-+ }
-+#else
-+ {
-+ KMALLOC(addr, bytes, gfp_flags);
-+ if ( addr && dma ) {
-+ *dma = virt_to_phys(addr);
-+ }
-+
-+ DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma);
-+ }
++#ifdef MUSB_HOST
++#define MUSB_VIRTHUB
+#endif
+
-+ if ( addr ) {
-+ memset(addr, 0, bytes);
-+ }
-+
-+ return addr;
-+}
++/************************* DEFINES DEPENDENT INCLUDES ************************/
+
-+/**
-+ * Free memory previously allocated with AllocBufferMemory.
-+ * @param pThis
-+ * @param bytes
-+ * @param dma
-+ */
-+void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma) {
++/* virtual hub */
++#include "musb_virthub.h"
+
-+ DBG(2, "<== freeing bytes=%d, address=%p, dma=%p\n", bytes, address, (void*)dma);
++/****************************** USB CONSTANTS ********************************/
+
-+#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21)
-+ DBG(2, "==>\n");
-+#else
-+ {
-+ KFREE(address);
-+ }
++#ifndef USB_DT_DEVICE_QUALIFIER
++#define USB_DT_DEVICE_QUALIFIER 6
+#endif
-+ DBG(2, "==>\n");
-+}
++
++#ifndef USB_DT_DEVICE_QUALIFIER_SIZE
++#define USB_DT_DEVICE_QUALIFIER_SIZE 10
+#endif
+
-+/* ------------------------------------------------------------------------ */
++#ifndef USB_DT_OTHER_SPEED
++#define USB_DT_OTHER_SPEED 7
++#endif
+
-+#ifndef MUSB_V26_POST10
-+/**
-+ * Private per-device allocation
-+ * @param pDevice Linux USBD device pointer
-+ * @return status code
-+ */
-+STATIC int mgc_linux_alloc_device(struct usb_device *pDevice)
-+{
-+
-+ DBG(2, "<==>\n");
-+ return 0;
-+
-+}
++#ifndef USB_MAXCHILDREN
++#define USB_MAXCHILDREN (16)
++#endif
+
-+/**
-+ * Private per-device cleanup
-+ * @param pDevice Linux USBD device pointer
-+ * @return 0 (success)
-+ */
-+STATIC int mgc_linux_free_device(struct usb_device * pDevice)
-+{
-+ DBG(2, "<==>\n");
-+ return 0;
-+}
++/****************************** DEBUG CONSTANTS ********************************/
+
-+int MGC_LinuxHubSuspend(struct usb_bus *pBus) {
-+ return 0;
-+}
++#define MGC_PAD_FRONT 0xa5deadfe
++#define MGC_PAD_BACK 0xabadcafe
++#define MGC_TEST_PACKET_SIZE 53
+
-+int MGC_LinuxHubResume(struct usb_bus *pBus) {
-+ return 0;
-+}
++/****************************** CONSTANTS ********************************/
+
++#if MUSB_DEBUG > 0
++#define STATIC
++#define MUSB_PARANOID
++#else
++#define STATIC static
+#endif
+
-+/* ------------------------------------------------------------------------ */
++#ifndef TRUE
++#define TRUE 1
++#endif
++#ifndef FALSE
++#define FALSE 0
++#endif
+
-+/**
-+ * Get the current frame number.
-+ * @param struct usb_hcd pointer to usb_hcd structure
-+ * @return frame number
-+ */
-+static inline int mgc_get_frame_number(MGC_LinuxCd* pThis) {
-+ uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+ const int no=(int)MGC_Read16(pBase, MGC_O_HDRC_FRAME);
++#ifndef MUSB_C_NUM_EPS
++#define MUSB_C_NUM_EPS ((uint8_t)16)
++#endif
+
-+ DBG(2, "<==> %d\n", no);
-+ return no;
-+}
++#ifndef MUSB_MAX_END0_PACKET
++#define MUSB_MAX_END0_PACKET ((uint16_t)MGC_END0_FIFOSIZE)
++#endif
+
-+/*
-+ */
-+int MGC_LinuxGetFrameNumber(struct usb_device* pDevice)
-+{
-+ MGC_LinuxCd* pThis=hcd_to_musbstruct(pDevice->bus->hcpriv);
-+ return mgc_get_frame_number( pThis );
-+}
++#define MGC_END0_START 0x0
++#define MGC_END0_OUT 0x2
++#define MGC_END0_IN 0x4
++#define MGC_END0_STATUS 0x8
+
++#define MGC_END0_STAGE_SETUP 0x0
++#define MGC_END0_STAGE_TX 0x2
++#define MGC_END0_STAGE_RX 0x4
++#define MGC_END0_STAGE_STATUSIN 0x8
++#define MGC_END0_STAGE_STATUSOUT 0xf
++#define MGC_END0_STAGE_STALL_BIT 0x10
+
-+/**************************************************************************
-+ * Linux driver hooks
-+**************************************************************************/
++/* obsolete */
++#define MGC_END0_STAGE_DATAIN MGC_END0_STAGE_TX
++#define MGC_END0_STAGE_DATAOUT MGC_END0_STAGE_RX
+
-+/**
-+ * Generic Interrupt Service Routine.
-+ * @param pThis the controller
-+ */
-+static irqreturn_t mgc_linux_isr(MGC_LinuxCd* pThis)
-+{
-+ uint32_t nSource;
-+#if MUSB_DEBUG > 0
-+ uint16_t wIntrTxCheck, wIntrRxCheck;
++/* EASY GUESS */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
++#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus, _port)
++#else
++/* 2.4, mvl21, bc5 */
++#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus)
+#endif
-+ const void* pBase = pThis->pRegs;
-+ uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+
-+ uint8_t power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+
-+ uint8_t bIntrUsbValue=MGC_Read8(pBase, MGC_O_HDRC_INTRUSB);
-+ uint16_t wIntrTxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
-+ uint16_t wIntrRxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRRX);
-+
-+ nSource = bIntrUsbValue | wIntrTxValue | wIntrRxValue;
-+ DEBUG_CODE(10, if (!nSource) { \
-+ INFO("IRQ [mode=%s] nSource=%d\n", MUSB_MODE(pThis), nSource); } );
+
+
-+ if (!nSource) {
-+ RETURN_IRQ_NONE;
-+ }
-+
-+ DBG(2, "<== [%ld]: IRQ RECEIVED [devmode=%s, hwmode=%s] IntrUSB=%02x, IntrUSBE=%02x, IntrTx=%04x, IntrRx=%04x\n",
-+ jiffies, MUSB_MODE(pThis), (devctl & MGC_M_DEVCTL_HM)?"host":"function",
-+ bIntrUsbValue, MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE),
-+ wIntrTxValue, wIntrRxValue);
-+
-+
-+ /* Recent IPs return the right values (not the masked one) */
-+ bIntrUsbValue &= MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE);
-+
-+
-+ /* corruption check */
-+#ifdef MUSB_PARANOID
-+ if ( MGC_ISCORRUPT(pThis) ) {
-+ INFO("stopping before ISR, the controller structure is corrupted\n");
-+ MGC_HdrcStop(pThis);
-+ MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
++/* 2.4/2.6 compatibility */
++#ifdef MUSB_V26
+
-+ RETURN_IRQ_HANDLED;
-+ }
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
++#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) ((_dev)->bus->op->disable(_dev, _pipe_ep))
++#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
++#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) ( 0 )
++#else
++#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
++#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
++#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
+#endif
+
-+#ifdef MUSB_DMA
-+ /* ### DMA intr handler added */
-+ if ( pThis->pDmaController->pfDmaControllerIsr(pThis->pDmaController->pPrivateData) ) {
-+ DBG(1, "%s: ******** DMA interrupt *************\n",__FUNCTION__);
-+ nSource |= 1;
-+ }
-+#endif
++/*#define COMPLETE_URB(_pUrb, _p) _pUrb->complete(_pUrb, _p)*/
++#define COMPLETE_URB(_pUrb, _p) (_pUrb->complete=_p)
++#define WAIT_MS(_ms) mdelay(_ms)
+
++#define USB_ISO_ASAP 0x0002
++#define USB_ASYNC_UNLINK 0x0008
+
-+ /* the core can interrupt us for multiple reasons, I.E. more than an
-+ * interrupt line can be asserted; service the globa interrupt first.
-+ * Global interrups are used to signal connect/disconnect/vbuserr
-+ * etc. processed in two phase */
-+ if ( bIntrUsbValue ) {
-+ DBG(3, "** IRQ [mode=%s] nSource=%d | DEVCTL :0x%x | IntrUsb:0x%x \n", \
-+ MUSB_MODE(pThis), nSource, MGC_Read8(pBase, MGC_O_HDRC_DEVCTL), bIntrUsbValue);
-+ mgc_hdrc_service_usb_stage0(pThis, bIntrUsbValue, devctl, power);
-+ }
++#define USB_ST_NOERROR (0)
++#define USB_ST_CRC (-EILSEQ)
++#define USB_ST_BITSTUFF (-EPROTO)
++#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */
++#define USB_ST_DATAOVERRUN (-EOVERFLOW)
++#define USB_ST_DATAUNDERRUN (-EREMOTEIO)
++#define USB_ST_BUFFEROVERRUN (-ECOMM)
++#define USB_ST_BUFFERUNDERRUN (-ENOSR)
++#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */
++#define USB_ST_SHORT_PACKET (-EREMOTEIO)
++#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */
++#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */
++#define USB_ST_URB_PENDING (-EINPROGRESS)
++#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */
++#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/
++#define USB_ST_NOTSUPPORTED (-ENOSYS)
++#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */
++#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */
++#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */
++#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/
+
-+#ifdef MUSB_PARANOID
-+ if ( wIntrTxValue || wIntrRxValue ) { /* got data! */
-+ if ( ((devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_HST(pThis)))
-+ || (!(devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_DEV(pThis))) )
-+ {
-+ if ( bIntrUsbValue ) {
-+ mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
-+ } else {
-+ WARN("early interrupt while in hm=%d: otg machine hasn't done yet\n",
-+ devctl & MGC_M_DEVCTL_HM);
-+ }
++#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs always with zero length packet */
+
-+ RETURN_IRQ_HANDLED;
-+ }
-+ }
+#endif
+
-+ /* ignore requests when in error */
-+ if( MUSB_IS_ERR(pThis) ) {
-+ if ( bIntrUsbValue) {
-+ mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
-+ } else {
-+ ERR("Error mode, please ZAP the driver!\n");
-+ mgc_hdrc_disable(pThis);
-+ }
-+
-+ RETURN_IRQ_HANDLED;
-+ }
-+
-+ /* handle tx/rx on endpoints; each bit of wIntrTxValue is an endpoint,
-+ * endpoint 0 first (p35 of the manual) bc is "SPECIAL" treatment;
-+ * WARNING: when operating as device you might start receving traffic
-+ * to ep0 before anything else happens so be ready for it */
-+ do {
-+ uint8_t bShift=0;
-+ uint32_t reg=wIntrTxValue;
++#ifdef MUSB_V24
++#define usb_disabled() 0
++#define COMPLETE_URB(_pUrb, _p) _pUrb->complete(_pUrb)
++#define WAIT_MS(_ms) wait_ms(_ms)
++#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
++#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
+
-+ if(reg & 1 ) { /* EP0 */
-+ if (devctl & MGC_M_DEVCTL_HM) {
-+#ifdef MUSB_CONFIG_PROC_FS
-+ if(pThis->pfDefaultEndHandler) {
-+ pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam);
-+ } else
-+#endif
-+ MGC_HdrcServiceDefaultEnd(pThis);
-+ } else {
-+ udc_ep0_irq();
-+ }
-+ }
-+
-+#ifdef MUSB_PARANOID
-+ if( MGC_ISCORRUPT(pThis) ) {
-+ INFO("after servicing Ep0 interrupt\n");
-+ break;
-+ }
-+#endif
-+
-+ /* TX on endpoints 1-15 */
-+ bShift = 1;
-+ reg >>= 1;
-+ while(reg) {
-+ if(reg & 1) {
-+ if(devctl & MGC_M_DEVCTL_HM) {
-+ MGC_HdrcServiceTxAvail(pThis, bShift);
-+ } else {
-+ udc_ep_tx_irq(bShift) ;
-+ }
-+ }
-+ reg >>= 1;
-+ bShift++;
-+ }
-+
-+ DEBUG_CODE(10, wIntrTxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRTX); \
-+ if(wIntrTxCheck && (wIntrTxCheck == wIntrTxValue)) { \
-+ ERR("Unhandled TX interrupt, wIntrTx=%04x wIntrTxCheck=%04x; DRC stopped\n",\
-+ wIntrTxValue, wIntrTxCheck); \
-+ for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \
-+ MGC_HdrcDumpRegs(pThis->pRegs, \
-+ MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \
-+ } \
-+ MGC_HdrcStop(pThis); \
-+ MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \
-+ MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \
-+ pThis->pRootDevice = NULL; \
-+ } );
-+
-+#ifdef MUSB_PARANOID
-+ if( MGC_ISCORRUPT(pThis) ) {
-+ INFO("after servicing Tx interrupt\n");
-+ break;
-+ }
-+#endif
-+
-+ /* RX on endpoints 1-15 */
-+ reg = wIntrRxValue;
-+ bShift = 1;
-+ reg >>= 1;
-+ while(reg) {
-+ if(reg & 1) {
-+ if(devctl & MGC_M_DEVCTL_HM) {
-+ MGC_HdrcServiceRxReady(pThis, bShift);
-+ } else {
-+ udc_ep_rx_irq(bShift) ;
-+ }
-+ }
-+
-+ reg >>= 1;
-+ bShift++;
-+ }
-+
-+ DEBUG_CODE(10, wIntrRxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRRX); \
-+ if(wIntrRxCheck && (wIntrRxCheck == wIntrRxValue)) { \
-+ DBG(1, "Unhandled RX interrupt, IntrRx=%04x; IntrRxCheck=%04x DRC stopped\n", \
-+ wIntrRxValue, wIntrRxCheck); \
-+ for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \
-+ MGC_HdrcDumpRegs(pThis->pRegs, \
-+ MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \
-+ } \
-+ MGC_HdrcStop(pThis); \
-+ MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \
-+ MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \
-+ pThis->pRootDevice = NULL; \
-+ });
-+
-+ /* Global interrups are used to signal connect/disconnect/vbuserr
-+ * etc. processed in two phase */
-+ if (bIntrUsbValue) {
-+ mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
-+ }
-+
-+#ifdef MUSB_PARANOID
-+ if( MGC_ISCORRUPT(pThis) ) {
-+ INFO("stopping after servicing Rx interrupt\n");
-+ }
++#ifdef MUSB_LINUX_MV21
++#define usb_get_urb(_pUrb) _pUrb
++#define usb_put_urb(_pUrb)
++#undef MUSB_HAS_BUSNAME
+#endif
-+ } while (0);
+
-+#ifdef MUSB_PARANOID
-+ if( MGC_ISCORRUPT(pThis) ) {
-+ MGC_HdrcStop(pThis);
-+ MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
-+ }
+#endif
+
-+ DBG(2, "==> IRQ HANDLED [devmode=%s]\n", MUSB_MODE(pThis));
-+ RETURN_IRQ_HANDLED;
-+}
++typedef enum
++{
++ MGC_STATE_DEFAULT,
++ MGC_STATE_ADDRESS,
++ MGC_STATE_CONFIGURED
++} MGC_DeviceState;
+
++/* failure codes */
++#define MUSB_ERR_WAITING 1
++#define MUSB_ERR_VBUS -1
++#define MUSB_ERR_BABBLE -2
++#define MUSB_ERR_CORRUPTED -3
++#define MUSB_ERR_IRQ -4
++#define MUSB_ERR_SHUTDOWN -5
++#define MUSB_ERR_RESTART -6
+
-+/**
-+ * Interrupt service routine.
-+ * @param irq interrupt line associated with the controller
-+ * @param hci data structure for the host controller
-+ * @param r holds the snapshot of the processor's context before
-+ * the processor entered interrupt code. (not used here)
-+ */
-+#ifndef MUSB_USE_HCD_DRIVER
-+irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r)
-+{
++/****************************** FUNCTIONS ********************************/
+
-+ MGC_LinuxCd* pThis = (MGC_LinuxCd*)__hci;
-+ return mgc_linux_isr(pThis);
-+}
-+#endif
++#define KMALLOC(a,b,c) { lock_kernel(); a=kmalloc(b,c); unlock_kernel(); }
++#define KFREE(p) { lock_kernel(); kfree(p); unlock_kernel(); }
+
-+/*****************************************************/
++/*************************** REGISTER ACCESS ********************************/
+
-+void goto_host_mode(MGC_LinuxCd* pThis) {
-+ /* TODO: graceful Gadget shutdown */
-+ MUSB_HST_MODE(pThis);
-+#ifdef MUSB_USE_HCD_DRIVER
-+
++/* indexed vs. flat register model */
++#ifdef MUSB_FLAT_REG
++#define MGC_SelectEnd(_pBase, _bEnd)
++#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
++ MGC_Read8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
++#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
++ MGC_Read16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
++#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
++ MGC_Write8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
++#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
++ MGC_Write16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
+#else
-+
++#define MGC_SelectEnd(_pBase, _bEnd) \
++ MGC_Write8(_pBase, MGC_O_HDRC_INDEX, _bEnd)
++#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
++ MGC_Read8(_pBase, (_bOffset + 0x10))
++#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
++ MGC_Read16(_pBase, (_bOffset + 0x10))
++#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
++ MGC_Write8(_pBase, (_bOffset + 0x10), _bData)
++#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
++ MGC_Write16(_pBase, (_bOffset + 0x10), _bData)
+#endif
-+}
+
-+void goto_device_mode(MGC_LinuxCd* pThis) {
-+ /* TODO: graceful host shutdown */
-+ MUSB_DEV_MODE(pThis);
-+}
+
++/************************** ULPI Registers ********************************/
+
-+/* --------------------------------------------------------------------------
-+ * Init function
-+ *
-+ */
++/* Added in HDRC 1.9(?) & MHDRC 1.4 */
++/* ULPI pass-through */
++#define MGC_O_HDRC_ULPI_VBUSCTL 0x70
++#define MGC_O_HDRC_ULPI_REGDATA 0x74
++#define MGC_O_HDRC_ULPI_REGADDR 0x75
++#define MGC_O_HDRC_ULPI_REGCTL 0x76
+
-+#ifndef MUSB_USE_HCD_DRIVER
-+/** attach to the IRQ and update the controller structure.
-+ * @param nIrq the Irq number
-+ * @param pThis the controller
-+ * @return 0 if success (pThis is also update), negative is error
-+ */
-+static int mgc_request_irq(int nIrq, MGC_LinuxCd* pThis) {
-+ int rc=-ENODEV;
++/* extended config & PHY control */
++#define MGC_O_HDRC_ENDCOUNT 0x78
++#define MGC_O_HDRC_DMARAMCFG 0x79
++#define MGC_O_HDRC_PHYWAIT 0x7A
++#define MGC_O_HDRC_PHYVPLEN 0x7B /* units of 546.1 us */
++#define MGC_O_HDRC_HSEOF1 0x7C /* units of 133.3 ns */
++#define MGC_O_HDRC_FSEOF1 0x7D /* units of 533.3 ns */
++#define MGC_O_HDRC_LSEOF1 0x7E /* units of 1.067 us */
+
-+ pThis->nIrq = nIrq;
-+ /* the hcd driver will take care of that */
-+ do {
++/* Added in HDRC 1.9(?) & MHDRC 1.4 */
++/* ULPI */
++#define MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND 0x02
++#define MGC_M_ULPI_VBUSCTL_USEEXTVBUS 0x01
++#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08
++#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04
++#define MGC_M_ULPI_REGCTL_COMPLETE 0x02
++#define MGC_M_ULPI_REGCTL_REG 0x01
++/* extended config & PHY control */
++#define MGC_M_ENDCOUNT_TXENDS 0x0f
++#define MGC_S_ENDCOUNT_TXENDS 0
++#define MGC_M_ENDCOUNT_RXENDS 0xf0
++#define MGC_S_ENDCOUNT_RXENDS 4
++#define MGC_M_DMARAMCFG_RAMBITS 0x0f /* RAMBITS-1 */
++#define MGC_S_DMARAMCFG_RAMBITS 0
++#define MGC_M_DMARAMCFG_DMACHS 0xf0
++#define MGC_S_DMARAMCFG_DMACHS 4
++#define MGC_M_PHYWAIT_WAITID 0x0f /* units of 4.369 ms */
++#define MGC_S_PHYWAIT_WAITID 0
++#define MGC_M_PHYWAIT_WAITCON 0xf0 /* units of 533.3 ns */
++#define MGC_S_PHYWAIT_WAITCON 4
+
-+#ifdef MUSB_HARD_IRQ
-+ if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_INTERRUPT,
-+ pThis->aName, pThis))
-+ {
-+ rc=0;
-+ pThis->nIrqType=SA_INTERRUPT;
-+ break;
-+ }
-+#endif
-+ if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_SHIRQ,
-+ pThis->aName, pThis))
-+ {
-+ rc=0;
-+ pThis->nIrqType=SA_SHIRQ;
-+ break;
-+ }
-+ } while (0);
-+
-+ return rc;
-+}
++/****************************** FUNCTIONS ********************************/
+
-+/**
-+ * release in irq previously allocated with mgc_request_irq().
-+* @param pTHis the controller the IRQ was allocated for
-+ */
-+static void mgc_free_irq(MGC_LinuxCd* pThis) {
-+ free_irq(pThis->nIrq, pThis);
-+}
-+#endif
++#define MUSB_HST_MODE(_pthis) { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
++ (_pthis)->bIsA=1; (_pthis)->bFailCode=0; }
++#define MUSB_DEV_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
++ (_pthis)->bIsA=0; (_pthis)->bFailCode=0; }
++#define MUSB_B_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
++ (_pthis)->bIsA=0; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
++#define MUSB_A_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
++ (_pthis)->bIsA=1; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
++#define MUSB_ERR_MODE(_pthis, _cause) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
++ (_pthis)->bFailCode=_cause; }
+
-+#ifdef MUSB_VIRTHUB
-+#ifndef MUSB_USE_HCD_DRIVER
-+static int mgc_init_bus(MGC_LinuxCd *pThis, void* pDevice)
-+{
-+ int rc=0;
-+
-+ /* allocate and register bus */
-+ pThis->pBus=usb_alloc_bus( &MGC_LinuxOperations );
-+ if (!pThis->pBus ) {
-+ return -ENODEV;
-+ }
++#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
++#define MUSB_IS_HST(_x) ( !MUSB_IS_ERR(_x) && (_x)->bIsHost && !(_x)->bIsDevice )
++#define MUSB_IS_DEV(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && (_x)->bIsDevice )
++#define MUSB_IS_B_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && !(_x)->bIsA )
++#define MUSB_IS_A_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && (_x)->bIsA )
+
-+#ifdef MUSB_V26
-+ pThis->pBus->controller =(struct device*)pDevice;
-+#endif
++#define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST":( MUSB_IS_DEV(_x)?"FUNCTION":(MUSB_IS_B_IDLE(_x)?"B_IDLE":(MUSB_IS_A_IDLE(_x)?"A_IDLE":"ERROR"))) )
+
-+#ifdef MUSB_HAS_BUSNAME
-+ pThis->pBus->bus_name = pThis->aName;
-+#endif
++#define HDRC_IS_HST(_x) ( MGC_Read8((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM )
++#define HDRC_IS_DEV(_x) ( !HDRC_IS_HST(_x) )
+
-+ /* when using the HCD driver (USE_HCD_DRIVER)
-+ pThis->pBus->hcpriv points to the hcd driver
-+ */
-+ pThis->pBus->hcpriv = (void *)pThis;
+
-+ usb_register_bus(pThis->pBus);
-+ INFO("Registered new bus @%p\n", pThis->pBus);
-+
-+ rc=mgc_init_root_hub(pThis);
-+ if ( rc!=0 ) {
-+ usb_deregister_bus(pThis->pBus);
-+ } else {
-+ pThis->pBus->root_hub = pThis->RootHub.pDevice;
-+ }
-+
-+ return rc;
-+}
++/******************************** DMA TYPES **********************************/
+
-+static void mgc_free_bus(struct usb_bus *bus) {
-+#ifdef MUSB_V26
-+ usb_deregister_bus(bus);
-+#endif
-+}
++#ifdef MUSB_DMA
++#include "dma.h"
+
++#ifndef MGC_HSDMA_CHANNELS
++#define MGC_HSDMA_CHANNELS 8
+#endif
++
++#ifdef MUSB_HAS_DMA_URBS
++#define WANTS_DMA(_pUrb) ((_pUrb)->transfer_dma && (_pUrb->flags & URB_NO_TRANSFER_DMA_MAP))
++#define DMA_BUFFER(_pUrb) ((_pUrb)->transfer_dma)
++#else
++#define WANTS_DMA(_pUrb) (0)
++#define DMA_BUFFER(pUrb) ((void*)0x000666)
+#endif
+
-+/* disable an endpoint */
-+#ifdef MUSB_V26
-+void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress)
-+{
-+ /* to do */
-+}
++extern MGC_DmaControllerFactory MGC_HdrcDmaControllerFactory;
+#endif
+
+
-+/* --------------------------------------------------------------------------
-+ * HOST DMA related code
-+ *
-+ */
++/************************** Ep Configuration ********************************/
+
-+#ifdef MUSB_DMA
-+/**
-+ * used ONLY in host mode, I'll be moved to musb_host
-+ * @param pPrivateData
-+ * @param bLocalEnd
-+ * @param bTransmit
-+ */
-+STATIC uint8_t MGC_LinuxDmaChannelStatusChanged(
-+ void* pPrivateData, uint8_t bLocalEnd, uint8_t bTransmit)
-+{
-+ MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
-+ MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bLocalEnd]);
-+ struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
-+ const void* pBase = pThis->pRegs;
-+ uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++/** The End point descriptor */
++struct MUSB_EpFifoDescriptor {
++ uint8_t bType; /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */
++ uint8_t bDir; /* 0 for autoconfig, INOUT, IN, OUT */
++ uint16_t wSize; /* 0 for autoconfig, or the size */
++ uint8_t bDbe; /* Double buffering: 0 disabled, 1 enabled */
++};
+
-+ if(!bLocalEnd) {
-+ /* endpoint 0 */
-+ if(devctl & MGC_M_DEVCTL_HM) {
-+#ifdef MUSB_CONFIG_PROC_FS
-+ if(pThis->pfDefaultEndHandler) {
-+ pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam);
-+ } else
-+#endif
-+ MGC_HdrcServiceDefaultEnd(pThis);
-+ } else {
-+ MGC_HdrcServiceDeviceDefaultEnd(pThis);
-+ }
-+ } else {
-+ /* endpoints 1..15 */
-+ if(bTransmit) {
-+ if(devctl & MGC_M_DEVCTL_HM) {
-+ MGC_HdrcServiceTxAvail(pThis, bLocalEnd);
-+ } else {
-+ MGC_HdrcServiceDeviceTxAvail(pThis, bLocalEnd);
-+ }
-+ } else {
-+ /* receive */
-+ if(devctl & MGC_M_DEVCTL_HM) {
-+ MGC_HdrcServiceRxReady(pThis, bLocalEnd);
-+ } else {
-+ MGC_HdrcServiceDeviceRxReady(pThis, bLocalEnd);
-+ }
-+ }
-+ }
-+
-+ /* trick: if end's URB changed; previous one completed;
-+ * probably not needed now... */
-+ return (pUrb == MGC_GetCurrentUrb(pEnd)) ? FALSE : TRUE;
-+}
-+#endif
++#define MUSB_EPD_AUTOCONFIG 0
+
-+/*-------------------------------------------------------------------------*/
++#define MUSB_EPD_T_CNTRL 1
++#define MUSB_EPD_T_ISOC 2
++#define MUSB_EPD_T_BULK 3
++#define MUSB_EPD_T_INTR 4
+
-+#ifdef MUSB_USE_HCD_DRIVER
-+#include "musb_hcd.c"
-+#endif
++#define MUSB_EPD_D_INOUT 0
++#define MUSB_EPD_D_TX 1
++#define MUSB_EPD_D_RX 2
++
++/******************************** TYPES *************************************/
++
++struct urb;
++struct usb_device;
++struct usb_gadget;
++struct usb_hcd;
+
+/**
-+ * Perform generic per-controller initialization.
-+ *
-+ * @param pDevice
-+ * @param nIrq IRQ (interpretation is system-dependent)
-+ * @param pRegs pointer to controller registers,
-+ * assumed already mapped into kernel space
-+ * @param pName name for bus
++ * The device request.
+ */
++typedef struct __attribute__((packed)) {
++ uint8_t bmRequestType;
++ uint8_t bRequest;
++ uint16_t wValue;
++ uint16_t wIndex;
++ uint16_t wLength;
++} MUSB_DeviceRequest;
+
-+MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType,
-+ int nIrq, void* pRegs, u64 len, const char* pName)
++/**
++ * MGC_LinuxLocalEnd.
++ * Local endpoint resource.
++ * @field Lock spinlock
++ * @field pUrb current URB
++ * @field urb_list list
++ * @field dwOffset current buffer offset
++ * @field dwRequestSize how many bytes were last requested to move
++ * @field wMaxPacketSizeTx local Tx FIFO size
++ * @field wMaxPacketSizeRx local Rx FIFO size
++ * @field wPacketSize programmed packet size
++ * @field bIsSharedFifo TRUE if FIFO is shared between Tx and Rx
++ * @field bAddress programmed bus address
++ * @field bEnd programmed remote endpoint address
++ * @field bTrafficType programmed traffic type
++ * @field bIsClaimed TRUE if claimed
++ * @field bIsTx TRUE if current direction is Tx
++ * @field bIsReady TRUE if ready (available for new URB)
++ */
++typedef struct
+{
-+ uint8_t bEnd;
-+ MGC_LinuxCd* pThis;
-+#ifdef MUSB_USE_HCD_DRIVER
-+ struct usb_hcd *hcd = NULL;
++#if MUSB_DEBUG > 0
++ uint32_t dwPadFront;
+#endif
-+ MGC_LinuxLocalEnd* pEnd;
-+ uint16_t temp;
-+ DBG(2, "<==\n");
-+
-+ /* allocate */
-+ INFO("MUSB Driver [Base Address(PA)=0x%p] [IRQ = %d] [pDevice=%p]\n",
-+ pRegs , nIrq, pDevice);
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ ///////////////////////////////////////////////////////////////////////////////
-+ /* allocate */
-+
-+
-+ hcd = usb_create_hcd(&musb_ahb_hc_driver, (struct device*)pDevice,
-+ ((struct device*)pDevice)->bus_id);
-+ hcd1=hcd;
-+ if ( !hcd ) {
-+ return NULL;
-+ }
-+
-+ hcd->rsrc_len = len;
-+ /* register Base address (VA)*/
-+ hcd->regs = pRegs;
-+ ///////////////////////////////////////////////////////////////////////////////
++ spinlock_t Lock;
++ uint8_t bEnd; /* ep number */
+
-+ pThis=hcd_to_musbstruct(hcd);
-+ udc_address=pThis;
-+ spin_lock_init(&pThis->LocalQueue.urb_queue_lock);
-+ init_waitqueue_head(&pThis->waitqh);
-+#else
-+ KMALLOC(pThis, sizeof(MGC_LinuxCd), GFP_ATOMIC);
-+ if(!pThis) {
-+ ERR("kmalloc driver instance data failed\n");
-+ return NULL;
-+ }
-+ memset (pThis, 0, sizeof(MGC_LinuxCd));
++#ifdef MUSB_USE_HCD_DRIVER
++ struct urb* pCurrentUrb;
++#else
++ struct list_head urb_list;
+#endif
+
++ uint8_t bBusyCompleting; /* TRUE on Tx when the current urb is completing */
+
++ unsigned int dwOffset; /* offset int the current request */
++ unsigned int dwRequestSize; /* request size */
++ unsigned int dwIsoPacket;
++ unsigned int dwWaitFrame;
++ uint8_t bRetries;
+
-+ pThis->pRegs = pRegs;
-+
-+ strcpy(pThis->aName, pName);
-+ spin_lock_init(&pThis->Lock);
-+
-+#if MUSB_DEBUG > 0
-+ pThis->dwPadFront = MGC_PAD_FRONT;
-+ pThis->dwPadBack = MGC_PAD_BACK;
++#ifdef MUSB_DMA
++ MGC_DmaChannel* pDmaChannel;
+#endif
+
-+#ifdef MUSB_DMA
-+ pThis->pDmaController = MGC_HdrcDmaControllerFactory
-+ .pfNewDmaController(MGC_LinuxDmaChannelStatusChanged, pThis, (uint8_t*)pRegs);
-+ if(pThis->pDmaController) {
-+ DBG(2, "DMA initialized&enabled Address: 0x%p\n", pThis->pDmaController);
-+ pThis->pDmaController->pfDmaStartController(
-+ pThis->pDmaController->pPrivateData);
-+ }
++#ifdef MUSB_CONFIG_PROC_FS
++ unsigned long dwTotalTxBytes;
++ unsigned long dwTotalRxBytes;
++ unsigned long dwTotalTxPackets;
++ unsigned long dwTotalRxPackets;
++ unsigned long dwErrorTxPackets;
++ unsigned long dwErrorRxPackets;
++ unsigned long dwMissedTxPackets;
++ unsigned long dwMissedRxPackets;
+#endif
+
++ uint16_t wMaxPacketSizeTx;
++ uint16_t wMaxPacketSizeRx;
++ uint16_t wPacketSize;
++ uint8_t bDisableDma; /* not used now! */
++ uint8_t bIsSharedFifo;
+
-+ mgc_reset(pThis);
++ /* softstate, used from find_end() to determine a good match */
++ uint8_t bRemoteAddress;
++ uint8_t bRemoteEnd;
++ uint8_t bTrafficType;
++ uint8_t bIsClaimed; /* only for isoc and int traffic */
++ uint8_t bIsTx;
++ uint8_t bIsReady;
++ uint8_t bStalled; /* the ep has been halted */
+
-+ /* be sure interrupts are disabled before connecting ISR */
-+ mgc_hdrc_disable(pThis);
++#if MUSB_DEBUG > 0
++ uint32_t dwPadBack;
++#endif
++} MGC_LinuxLocalEnd;
+
-+ // Reset the device, otherwise the controller
-+ // can be in unknown state.
-+ temp = MGC_Read16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL);
++/** A listener for disconnection */
++typedef void (*MGC_pfDisconnectListener)(void*);
++/** A handler for the default endpoint interrupt */
++typedef void (*MGC_pfDefaultEndHandler)(void*);
+
-+ MGC_Write16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL, (temp |MGC_M_TOPCTRL_MODE_SRST));
++#ifdef MUSB_USE_HCD_DRIVER
++typedef struct {
++ spinlock_t urb_queue_lock;
++ int urb_queue_count;
++ int urb_exec_count;
++ void *urb_queue_head;
++ void *urb_queue_tail;
++} mgc_hcd_urb_queue;
++#endif
+
-+ /* discover configuration */
-+ if ( !MGC_HdrcInit(wType, pThis) ) {
-+#ifdef MUSB_USE_HCD_DRIVER
-+ /* free memory ? */
-+#else
-+ /* free memory ? */
++/**
++ * MGC_LinuxCd.
++ * Driver instance data.
++ * @field Lock spinlock
++ * @field Timer interval timer for various things
++ * @field pBus pointer to Linux USBD bus
++ * @field RootHub virtual root hub
++ * @field PortServices services provided to virtual root hub
++ * @field pRootDevice root device pointer, to track connection speed
++ * @field nIrq IRQ number (needed by free_irq)
++ * @field bIsMultipoint TRUE if multi-point core
++ * @field bIsHost TRUE if host
++ * @field bIsDevice TRUE if peripheral
++ * @field pRegs pointer to mapped registers
++ */
++typedef struct
++{
++#if MUSB_DEBUG > 0
++ uint32_t dwPadFront;
+#endif
-+ return NULL;
-+ }
-+ /*for nhk15 this a must for powering up the STULPI
-+ */
-+ /*power up the STULPI tranceiver*/
-+ MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);
-+
-+ /* print config */
-+ for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+ pEnd = &(pThis->aLocalEnd[bEnd]);
-+ if(pEnd->wMaxPacketSizeTx || pEnd->wMaxPacketSizeRx) {
-+ INFO("End %02d: %sFIFO TxSize=%04x/RxSize=%04x\n",
-+ bEnd, pEnd->bIsSharedFifo ? "Shared " : "",
-+ pEnd->wMaxPacketSizeTx, pEnd->wMaxPacketSizeRx);
-+ } else {
-+ INFO("End %02d: not configured\n", bEnd);
-+ }
-+ }
-+
-+ /* procfs and testing interface */
-+ MGC_LinuxCreateProcFs(pThis->aName, pThis);
++ spinlock_t Lock;
++ struct timer_list Timer;
++ struct usb_bus *pBus;
++ char aName[32];
++ MGC_VirtualHub RootHub;
++ MGC_PortServices PortServices;
++ struct usb_device* pRootDevice;
+
-+#ifdef MUSB_PROC_TESTMUSB
-+ MGC_LinuxCreateTestProcFs(pThis->aName, pThis);
++#ifdef MUSB_DMA
++ MGC_DmaController* pDmaController;
+#endif
+
-+ MUSB_B_IDLE_MODE(pThis);
-+ DBG(1, "MUSB_B_IDLE mode \n");
-+ temp = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL );
++ int nIrq;
++ int nIrqType;
+
-+ /* connect ISR */
++ int nBabbleCount;
++ void* pRegs;
+
++ MGC_LinuxLocalEnd aLocalEnd[MUSB_C_NUM_EPS];
+
+#ifdef MUSB_USE_HCD_DRIVER
-+ /* by default allocate shared IRQ */
-+ pThis->nIrq=nIrq;
-+ pThis->nIrqType=MUSB_DEFAULT_IRQTYPE;
-+#else
++ mgc_hcd_urb_queue LocalQueue;
++ wait_queue_head_t waitqh;
++#endif
+
++ uint16_t wEndMask;
++ uint8_t bEndCount;
++ uint8_t bRootSpeed;
++ uint8_t bIsMultipoint;
++ uint8_t bIsHost;
++ uint8_t bIsDevice;
++ uint8_t bIsA;
++ uint8_t bIgnoreDisconnect; /* during bus resets I got fake disconnects */
++ uint8_t bVbusErrors; /* bus errors found */
+
-+ if ( mgc_request_irq(nIrq, pThis)!=0 ) {
-+ err("request_irq %d failed!", nIrq);
-+ return NULL;
-+ }
-+#endif
++ int bFailCode; /* one of MUSB_ERR_* failure code */
+
++ uint8_t bBulkTxEnd;
++ uint8_t bBulkRxEnd;
++ uint8_t bBulkSplit;
++ uint8_t bBulkCombine;
+
++ uint8_t bEnd0Stage; /* end0 stage while in host or device mode */
+
-+if(udcinitmonitorflag_init==0){
-+nomadik_udc_init(udc_address);
-+}
++#ifdef MUSB_GADGET
++ uint8_t bDeviceState;
++ uint8_t bIsSelfPowered;
++ uint8_t bSetAddress;
++ uint8_t bAddress;
++ uint8_t bTestMode;
++ uint8_t bTestModeValue;
+
-+#ifdef MUSB_VIRTHUB
-+#ifdef MUSB_USE_HCD_DRIVER
-+ if ( usb_add_hcd(hcd, pThis->nIrq, pThis->nIrqType)!=0 ) {
-+ DBG(2, "==> Usb_add_hcd failed \n");
-+ return NULL;
-+ }
-+#else
-+ if( 0!=mgc_init_bus(pThis, pDevice) ) {
-+ dbg("usb_alloc_bus fail");
-+ mgc_free_irq(pThis);
-+ return NULL;
-+ }
-+
++ struct usb_gadget* pGadget; /* the gadget */
++ struct usb_gadget_driver* pGadgetDriver; /* it's driver */
++
++ /* Endpoint 0 buffer and its buffer code; can be customized for
++ * devices that are not usign the default USB headers. Default
++ * values are:
++ *
++ * . pfFillBuffer is MGC_HdrcReadUSBControlRequest()
++ * . pEnd0Buffer is an instance of MGC_End0Buffer
++ **/
++ int (*pfReadHeader)(void*, uint16_t); /* NULL==MGC_HdrcReadUSBControlRequest*/
++ void* pEnd0Buffer; /* this is the buffer, default implementation uses MGC_End0Buffer */
++
++ /* compatibility, need to be osoleted used from gstorage */
++ uint16_t wEnd0Offset;
+#endif
-+#endif
-+udcinitmonitorflag_isr=1;
-+init_timer(¬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 <asm/uaccess.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/proc_fs.h>
++ if(MGC_PAD_FRONT != pThis->dwPadFront) {
++ printk(KERN_INFO"musb %s:%d: pThis front pad corrupted (%x)\n",
++ function, line, pThis->dwPadFront);
++ return TRUE;
++ }
+
-+#include <linux/usb.h>
-+#include "musbdefs.h"
-+#include "musb_ioctl.h"
++ if(MGC_PAD_BACK != pThis->dwPadBack) {
++ printk(KERN_INFO"musb %s:%d: pThis back pad corrupted (%x)\n",
++ function, line, pThis->dwPadBack);
++ return TRUE;
++ }
+
-+/* ----------------------------------------------------------------------- */
++#ifdef MUSB_HOST
++ for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++ pEnd = &(pThis->aLocalEnd[bEnd]);
+
-+#if MUSB_DEBUG > 0
-+static int atoi(char* buffer, int base, int len) {
-+ int result=0, digit=0;
-+
-+ while ( len-->0 && (*buffer) ) {
-+ digit=((*buffer>='0') && (*buffer<='9'))
-+ ? *buffer-'0'
-+ : ((*buffer>='a') && (*buffer<='f'))
-+ ? *buffer-'a'
-+ : -1;
-+
-+ if ( digit<0 ) {
-+ break;
++ if(MGC_PAD_FRONT != pEnd->dwPadFront) {
++ printk(KERN_INFO"musb %s:%d: end %d front pad corrupted (%x)\n",
++ function, line, bEnd, pEnd->dwPadFront);
++ return TRUE;
+ }
-+
-+ buffer++;
-+ result=result*base+digit;
-+ }
-+
-+ return result;
-+}
+
-+static int atoi_from_user(const char* buffer, int count) {
-+ char digits[8];
-+ int len=min(count, 8);
-+ copy_from_user(&digits, buffer, len);
-+ return atoi(digits, 10, len);
-+}
++ if(MGC_PAD_BACK != pEnd->dwPadBack) {
++ printk(KERN_INFO"musb %s:%d: end %d back pad corrupted (%x)\n",
++ function, line, bEnd, pEnd->dwPadBack);
++ return TRUE;
++ }
++ }
++#endif
+
++#ifdef MUSB_GADGET
++ /* do something about it */
++#endif
+
-+static const char* decode_address(int index) {
-+ static const char* COMMON_REGISTER_MAP[] = {
-+ "FAddr", "Power", "IntrTx", "IntrRx",
-+ "IntrTxE", "IntrRxE", "IntrUSB", "IntrUSBE",
-+ "Frame", "Index","TestMode" };
-+ return (index<11) ? COMMON_REGISTER_MAP[index]:NULL;
++ return FALSE;
+}
-+#endif
+
-+/* ----------------------------------------------------------------------- */
++#else
++#define MGG_IsCorrupt(_x) (_x)
++#define MGC_HDRC_DUMPREGS(_t, _s)
++#endif
+
++/* -------------------------- Host Definitions ------------------------ */
+
-+/* Write to ProcFS
-+ *
-+ * C soft-connect
-+ * c soft-disconnect
-+ * I enable HS
-+ * i disable HS
-+ * R resume bus
-+ * S start session (OTG-friendly when OTG-compiled)
-+ * s stop session
-+ * F force session (OTG-unfriendly)
-+ * E rElinquish bus (OTG)
-+ * H request host mode
-+ * h cancel host request
-+ * P disable the low-power mode that kills us in peripheral mode
-+ * D<num> set/query the debug level
-+ * Z zap
-+ */
-+static int MGC_ProcWrite(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ char cmd;
-+ uint8_t bReg;
-+ uint8_t* pBase=((MGC_LinuxCd*)data)->pRegs;
-+
-+ /* MOD_INC_USE_COUNT; */
-+
-+ if(copy_from_user(&cmd, buffer, 1) == 0){
-+ switch(cmd) {
-+ case 'C':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_SOFTCONN;
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+ }
-+ break;
-+
-+ case 'c':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_SOFTCONN;
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+ }
-+ break;
-+
-+ case 'I':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_HSENAB;
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+ }
-+ break;
-+
-+ case 'i':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_HSENAB;
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+ }
-+ break;
-+
-+ case 'R':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg | MGC_M_POWER_RESUME);
-+ WAIT_MS(10);
-+ MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+ WARN("Power Resumed\n");
-+ } break;
-+
-+ case 'S':
-+ MGC_Session((MGC_LinuxCd*)data);
-+ break;
-+
-+
-+ case 's':
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+ bReg &= ~MGC_M_DEVCTL_SESSION;
-+ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+ break;
-+
-+ case 'F':
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+ bReg |= MGC_M_DEVCTL_SESSION;
-+ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+ break;
-+
-+ case 'H':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+ bReg |= MGC_M_DEVCTL_HR;
-+ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+ }
-+ break;
-+
-+ case 'h':
-+ if ( pBase ) {
-+ bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+ bReg &= ~MGC_M_DEVCTL_HR;
-+ MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+ }
-+ break;
-+
-+ /* Xap the controller */
-+ case 'Z':
-+ MGC_Zap((MGC_LinuxCd*)data);
-+ break;
-+
-+#if (MUSB_DEBUG>0)
-+ /* read & write registers */
-+ case 'r':
-+ case 'w': {
-+ uint8_t index=0;
-+ uint32_t value=0;
-+ char command[64];
-+
-+ memset(command, 0, sizeof(command));
-+ copy_from_user(command, buffer, min(count, (unsigned long)63));
-+
-+ /* detrermine the index,
-+ * only the adrress now */
-+ index=atoi(&command[2], 16, count-2);
-+ if ( index>0 && pBase ) {
-+ const char *address=decode_address(index);
-+
-+ if ( buffer[0]=='r' ) {
-+ value=(command[1]=='8')
-+ ? MGC_Read8(pBase, index)
-+ : (command[1]=='f')
-+ ? MGC_Read16(pBase, index)
-+ : 0;
-+ } else {
-+ /* not write, not yet... */
-+ index=-1;
-+ }
-+
-+ if ( address ) {
-+ INFO("%s=0x%x\n", address, value);
-+ } else {
-+ INFO("0x%x=0x%x\n", index, value);
-+ }
-+ }
-+ } break;
-+
-+ /* set/read debug level */
-+ case 'D': {
-+ if ( count>1 ) {
-+ int level=0;
-+ level=atoi_from_user(&buffer[1], count-1);
-+ MGC_SetDebugLevel(level);
-+ } else {
-+ INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel);
-+ /* & dump the status to syslog */
-+ }
-+ } break;
-+
-+ /* display queue status */
-+ case 'Q': {
-+ int index=-1;
-+ char endb[256];
-+ MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
-+
-+ if (count>2) {
-+ index=atoi_from_user(&buffer[1], count-1);
-+ }
-+
-+ if ( dump_header_stats(pThis, endb)>0 ) {
-+ printk(KERN_INFO"%s", endb);
-+ }
-+
+#ifdef MUSB_HOST
-+ if( MUSB_IS_HST(pThis) ) {
-+ if ( index<0 ) {
-+ uint8_t bEnd;
-+
-+ /* generate the report for the end points */
-+ for (bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+ if ( dump_end_stats(pThis, bEnd, endb)>0 ) {
-+ printk(KERN_INFO"%s", endb);
-+ }
-+ }
-+
-+ } else {
-+ if ( dump_end_stats(pThis, index, endb)>0 ) {
-+ printk(KERN_INFO"%s", endb);
-+ }
-+ }
-+ }
-+#endif
-+
-+
-+ } break;
-+
-+ case 'd': {
-+ if ( count>1 ) {
-+ int delay=atoi_from_user(&buffer[1], count-1);
-+ MGC_SetDeviceDelay(delay);
-+ }
-+ INFO("mgc_slow_device_kludge_delay=%d\n",
-+ MGC_SetDeviceDelay(-1));
-+ } break;
-+
-+ /* flush */
-+ case '?':
-+ INFO("?: you are seeing it\n");
-+ INFO("C/c: soft connect enable/disable\n");
-+ INFO("I/i: hispeed enable/disable\n");
-+ INFO("S/s: session set/clear\n");
-+ INFO("F: \n");
-+ INFO("H: host mode\n");
-+ INFO("r/w: read write register\n");
-+ INFO("Z: zap\n");
-+ INFO("D: set/read dbug level\n");
-+ INFO("Q: show queue status\n");
-+ break;
-+#endif
-+
-+ default:
-+ ERR("Command %c not implemented\n", cmd);
-+ break;
-+ }
-+ }
-+
-+ return count;
-+}
-+
++extern void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis);
++#endif
+
-+/**
-+ * Read from /proc filesystem.
-+ * @param
-+ * @param
-+ * @param
-+ * @param
-+ * @param
-+ * @param
-+ */
-+static int MGC_ProcRead(char *page, char **start,
-+ off_t off, int count, int *eof, void *data)
-+{
-+ off_t len=0;
-+ char *buffer;
-+ int rc=0, code=0;
-+ unsigned long flags;
-+ MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
++/* -------------------------- Gadget Definitions --------------------- */
+
-+ spin_lock_irqsave(&pThis->Lock, flags);
++struct usb_ep;
+
-+ buffer=kmalloc(4*1024, GFP_USER);
-+ if ( !buffer ) {
-+ ERR("Out of memory\n");
-+ return -1;
-+ }
-+
-+ /* generate the report for the end points */
-+ code=dump_header_stats(pThis, buffer);
-+ if ( code>0 ) {
-+ len+=code;
-+ }
-+
-+#ifdef MUSB_HOST
-+ if( MUSB_IS_HST(pThis) ) {
-+
-+ uint8_t bEnd;
++extern const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE];
+
-+ for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+ code=dump_end_stats(pThis, bEnd, &buffer[len]);
-+ if ( code>0 ) {
-+ len+=code;
-+ }
-+ }
-+ }
++#if defined(MUSB_GADGET) || defined(MUSB_V26)
++void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma);
++void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma);
+#endif
+
-+ if ( off<len ) {
-+ int i=0, togo=len-off;
-+ char *s=&buffer[off],*d=page;
-+
-+ if ( togo>count ) {
-+ togo=count;
-+ }
-+
-+ while ( i++<togo ) {
-+ *d++=*s++;
-+ }
-+
-+ rc=togo;
-+ } else {
-+ *buffer=0;
-+ *eof=1;
-+ }
++#ifdef MUSB_GADGET
++extern void* MGC_MallocEp0Buffer(const MGC_LinuxCd* pThis);
++#endif
+
-+ kfree(buffer);
-+ spin_unlock_irqrestore(&pThis->Lock, flags);
-+ return rc;
-+}
++/* Gadget functions */
++#ifdef MUSB_GADGET
++struct usb_gadget;
+
++extern MGC_LinuxCd* MGC_GetDriverByName(const char *name);
++extern int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd);
++extern void mgc_init_gadget_endpoints(MGC_LinuxCd *pThis, struct usb_gadget *gadget);
++extern void MGC_GadgetReset(MGC_LinuxCd* pThis);
++extern void MGC_GadgetResume(MGC_LinuxCd* pThis);
++extern void MGC_GadgetSuspend(MGC_LinuxCd* pThis);
++extern void MGC_GadgetDisconnect(MGC_LinuxCd* pThis);
++extern void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis);
++extern void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
+
-+/**
-+ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
-+ * @param data the controller instance
-+ */
-+void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data) {
-+ remove_proc_entry(data->pProcEntry->name, NULL);
-+}
++extern void dump_ep_status(MGC_LinuxCd* pThis);
++extern void dump_ep_queue(int index, int verbose);
+
-+/**
-+ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
-+ * @param data the controller instance
++/*
++ * Gadget disabled
+ */
-+void MGC_LinuxRemoveProcFs(MGC_LinuxCd* data) {
-+ remove_proc_entry(data->pProcEntry->name, NULL);
-+}
++#else
++#define GADGET_DISABLED(_x) { DBG(0, "#GADGET DISABLED"); _x }
+
-+/**
-+ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
-+ * @param name
-+ * @param data the controller instance
-+ */
-+struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, MGC_LinuxCd* data) {
-+ if ( !name ) {
-+ name=data->aName;
-+ }
++static inline MGC_LinuxCd* MGC_GetDriverByName(const char *name)
++ GADGET_DISABLED( return NULL; )
++static inline int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd)
++ GADGET_DISABLED( return -1; )
++static inline void MGC_InitGadgetEndPoints(MGC_LinuxCd *pThis)
++ GADGET_DISABLED(;)
++static inline void MGC_GadgetReset(MGC_LinuxCd* pThis)
++ GADGET_DISABLED(;)
++static inline void MGC_GadgetResume(MGC_LinuxCd* pThis)
++ GADGET_DISABLED(;)
++static inline void MGC_GadgetSuspend(MGC_LinuxCd* pThis)
++ GADGET_DISABLED(;)
++static inline void MGC_GadgetDisconnect(MGC_LinuxCd* pThis)
++ GADGET_DISABLED(;)
++static inline void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis)
++ GADGET_DISABLED(;)
++static inline void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd)
++ GADGET_DISABLED(;)
++static inline void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
++ GADGET_DISABLED(;)
+
-+ data->pProcEntry=create_proc_entry(name,
-+ S_IFREG | S_IRUGO | S_IWUSR, NULL);
-+ if( data->pProcEntry )
-+ {
-+ data->pProcEntry->data = data;
-+#ifdef MUSB_V26
-+ data->pProcEntry->owner=THIS_MODULE;
++static inline void dump_ep_status(MGC_LinuxCd* pThis)
++ GADGET_DISABLED(;)
++static inline void dump_ep_queue(int index, int verbose)
++ GADGET_DISABLED(;)
+#endif
-+
-+ data->pProcEntry->read_proc = MGC_ProcRead;
-+ data->pProcEntry->write_proc = MGC_ProcWrite;
-+
-+ data->pProcEntry->size = 0;
-+
-+ dbg("Registered /proc/%s\n", name);
-+ } else {
-+ dbg ("Cannot create a valid proc file entry");
-+ }
+
-+ return data->pProcEntry;
-+}
+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.c
---- linux-2.6.20/drivers/usb/nomadik/musb_virthub.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.c 2008-07-28 15:21:03.000000000 +0530
-@@ -0,0 +1,840 @@
++#endif /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musbhdrc.h
+@@ -0,0 +1,315 @@
+/*
-+ * linux/drivers/usb/nomadik/musb_virthub.c
++ * linux/drivers/usb/nomadik/musbhdrc.h
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++#ifndef __MUSB_HDRC_DEFS_H__
++#define __MUSB_HDRC_DEFS_H__
+
-+//#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/time.h>
-+#include <linux/timer.h>
++/*
++ * HDRC-specific definitions
++ * $Revision: 1.8 $
++ */
+
-+#include <linux/usb.h>
++#define MGC_MAX_USB_ENDS 16
+
-+#ifndef MUSB_LINUX_MV21
-+#include "../core/hcd.h"
-+#define HAS_USB_TT_MULTI
-+#else
-+#include <hub.h>
-+#endif
++#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */
+
-+#include "musbdefs.h"
++/*
++ * MUSBMHDRC Register map
++ */
+
-+/******************************* FORWARDS ********************************/
++/* Common USB registers */
+
-+static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub,
-+ void (*pfExpired)(unsigned long), unsigned long timeout);
-+static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb);
-+static void MGC_VirtualHubTimerExpired(unsigned long ptr);
++#define MGC_O_HDRC_FADDR 0x00 /* 8-bit */
++#define MGC_O_HDRC_POWER 0x01 /* 8-bit */
+
-+/******************************* GLOBALS *********************************/
++#define MGC_O_HDRC_INTRTX 0x02 /* 16-bit */
++#define MGC_O_HDRC_INTRRX 0x04
++#define MGC_O_HDRC_INTRTXE 0x06
++#define MGC_O_HDRC_INTRRXE 0x08
++#define MGC_O_HDRC_INTRUSB 0x0A /* 8 bit */
++#define MGC_O_HDRC_INTRUSBE 0x0B /* 8 bit */
++#define MGC_O_HDRC_FRAME 0x0C
++#define MGC_O_HDRC_INDEX 0x0E /* 8 bit */
++#define MGC_O_HDRC_TESTMODE 0x0F /* 8 bit */
+
-+/** device descriptor */
-+static uint8_t MGC_aVirtualHubDeviceDesc[] =
-+{
-+ USB_DT_DEVICE_SIZE,
-+ USB_DT_DEVICE,
-+ 0x00, 0x02, /* bcdUSB */
-+ USB_CLASS_HUB, /* bDeviceClass */
-+ 0, /* bDeviceSubClass */
-+ 1, /* bDeviceProtocol (single TT) */
-+ 64, /* bMaxPacketSize0 */
-+ 0xd6, 0x4, /* idVendor */
-+ 0, 0, /* idProduct */
-+ 0, 0, /* bcdDevice */
-+ 0, /* iManufacturer */
-+ 0, /* iProduct */
-+ 0, /* iSerialNumber */
-+ 1 /* bNumConfigurations */
-+};
++/* Get offset for a given FIFO */
++#define MGC_FIFO_OFFSET(_bEnd) (0x20 + (_bEnd * 4))
+
-+/** device qualifier */
-+static uint8_t MGC_aVirtualHubQualifierDesc[] =
-+{
-+ USB_DT_DEVICE_QUALIFIER_SIZE,
-+ USB_DT_DEVICE_QUALIFIER,
-+ 0x00, 0x02, /* bcdUSB */
-+ USB_CLASS_HUB, /* bDeviceClass */
-+ 0, /* bDeviceSubClass */
-+ 0, /* bDeviceProtocol */
-+ 64, /* bMaxPacketSize0 */
-+ 0xd6, 0x4, /* idVendor */
-+ 0, 0, /* idProduct */
-+ 0, 0, /* bcdDevice */
-+ 0, /* iManufacturer */
-+ 0, /* iProduct */
-+ 0, /* iSerialNumber */
-+ 1 /* bNumConfigurations */
-+};
++/* Additional Control Registers */
+
-+/** Configuration descriptor */
-+static uint8_t MGC_VirtualHubConfigDesc[] =
-+{
-+ USB_DT_CONFIG_SIZE,
-+ USB_DT_CONFIG,
-+ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
-+ 0x01, /* bNumInterfaces */
-+ 0x01, /* bConfigurationValue */
-+ 0x00, /* iConfiguration */
-+ 0xE0, /* bmAttributes (self-powered, remote wake) */
-+ 0x00, /* MaxPower */
-+
-+ /* interface */
-+ USB_DT_INTERFACE_SIZE,
-+ USB_DT_INTERFACE,
-+ 0x00, /* bInterfaceNumber */
-+ 0x00, /* bAlternateSetting */
-+ 0x01, /* bNumEndpoints */
-+ USB_CLASS_HUB, /* bInterfaceClass */
-+ 0x00, /* bInterfaceSubClass */
-+ 0x00, /* bInterfaceProtocol */
-+ 0x00, /* iInterface */
-+
-+ /* endpoint */
-+ USB_DT_ENDPOINT_SIZE,
-+ USB_DT_ENDPOINT,
-+ USB_DIR_IN | 1, /* bEndpointAddress: IN Endpoint 1 */
-+ USB_ENDPOINT_XFER_INT, /* bmAttributes: Interrupt */
-+ (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0, /* wMaxPacketSize */
-+ 12 /* bInterval: 256 ms */
-+};
++#define MGC_O_HDRC_DEVCTL 0x60 /* 8 bit */
+
-+/** other-speed Configuration descriptor */
-+static uint8_t MGC_VirtualHubOtherConfigDesc[] =
-+{
-+ USB_DT_CONFIG_SIZE,
-+ USB_DT_OTHER_SPEED,
-+ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
-+ 0x01, /* bNumInterfaces */
-+ 0x01, /* bConfigurationValue */
-+ 0x00, /* iConfiguration */
-+ 0xE0, /* bmAttributes (self-powered, remote wake) */
-+ 0x00, /* MaxPower */
-+
-+ /* interface */
-+ USB_DT_INTERFACE_SIZE,
-+ USB_DT_INTERFACE,
-+ 0x00, /* bInterfaceNumber */
-+ 0x00, /* bAlternateSetting */
-+ 0x01, /* bNumEndpoints */
-+ USB_CLASS_HUB, /* bInterfaceClass */
-+ 0x00, /* bInterfaceSubClass */
-+ 0x00, /* bInterfaceProtocol */
-+ 0x00, /* iInterface */
-+
-+ /* endpoint */
-+ USB_DT_ENDPOINT_SIZE,
-+ USB_DT_ENDPOINT,
-+ USB_DIR_IN | 1, /* bEndpointAddress: IN Endpoint 1 */
-+ USB_ENDPOINT_XFER_INT, /* bmAttributes: Interrupt */
-+ (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0, /* wMaxPacketSize */
-+ 0xff /* bInterval: 255 ms */
-+};
++/* These are actually indexed: */
++#define MGC_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */
++#define MGC_O_HDRC_RXFIFOSZ 0x63 /* 8-bit (see masks) */
++#define MGC_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */
++#define MGC_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */
+
-+/****************************** FUNCTIONS ********************************/
++#define MGC_O_HDRC_TOPCONTROL 0x204 /* top control register 16-bit */
+
-+/**
-+ * Generic timer activation helper. Requires the hub structure to
-+ * be locked.
-+ *
-+ * @param pHub pointer to hub struct
-+ * @param pfExpired callback function
-+ * @param timeout millisecs
-+ * @requires spin_lock(pHub->Lock)
-+ */
-+static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub,
-+ void (*pfExpired)(unsigned long), unsigned long timeout)
-+{
-+ DBG(2, "<== pHub=%p, pHub->pUrb=%p\n", pHub, pHub->pUrb);
-+ del_timer(&pHub->Timer); /* make sure another timer is not running */
-+ init_timer(&(pHub->Timer));
-+ pHub->Timer.function = pfExpired;
-+ pHub->Timer.data = (unsigned long)pHub;
-+ pHub->Timer.expires = jiffies + timeout * HZ / 1000;
-+ add_timer( &(pHub->Timer) );
-+}
++/* offsets to registers in flat model */
++#define MGC_O_HDRC_TXMAXP 0x00
++#define MGC_O_HDRC_TXCSR 0x02
++#define MGC_O_HDRC_CSR0 MGC_O_HDRC_TXCSR /* re-used for EP0 */
++#define MGC_O_HDRC_RXMAXP 0x04
++#define MGC_O_HDRC_RXCSR 0x06
++#define MGC_O_HDRC_RXCOUNT 0x08
++#define MGC_O_HDRC_COUNT0 MGC_O_HDRC_RXCOUNT /* re-used for EP0 */
++#define MGC_O_HDRC_TXTYPE 0x0A
++#define MGC_O_HDRC_TYPE0 MGC_O_HDRC_TXTYPE /* re-used for EP0 */
++#define MGC_O_HDRC_TXINTERVAL 0x0B
++#define MGC_O_HDRC_NAKLIMIT0 MGC_O_HDRC_TXINTERVAL /* re-used for EP0 */
++#define MGC_O_HDRC_RXTYPE 0x0C
++#define MGC_O_HDRC_RXINTERVAL 0x0D
++#define MGC_O_HDRC_FIFOSIZE 0x0F
++#define MGC_O_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */
+
-+/**
-+ * Report the VHUB status bits. Assumes that pData has enough
-+ * storage for all of them.
-+ * @param pHub the hub
-+ * @param pData the data buffer status shoudl be written to
-+ * @return
-+ */
-+int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData) {
-+ int nPort, length=1;
-+ uint8_t bData=0, bBit=1;
-+
-+ /* count 1..N to accomodate hub status bit */
-+ for(nPort = 1; nPort <= pHub->bPortCount + 1; nPort++) {
-+ if(pHub->aPortStatusChange[nPort-1].wChange & 1) {
-+ bData |= 1 << bBit;
-+ }
-+
-+ if(++bBit > 7) {
-+ *pData++ = bData;
-+ bData = bBit = 0;
-+ length++;
-+ }
-+ }
-+
-+ if(bBit) {
-+ *pData++ = bData;
-+ }
++#define MGC_END_OFFSET(_bEnd, _bOffset) (0x100 + (0x10*_bEnd) + _bOffset)
+
-+ return length;
-+}
++/* "bus control" registers */
++#define MGC_O_HDRC_TXFUNCADDR 0x00
++#define MGC_O_HDRC_TXHUBADDR 0x02
++#define MGC_O_HDRC_TXHUBPORT 0x03
++
++#define MGC_O_HDRC_RXFUNCADDR 0x04
++#define MGC_O_HDRC_RXHUBADDR 0x06
++#define MGC_O_HDRC_RXHUBPORT 0x07
++
++#define MGC_BUSCTL_OFFSET(_bEnd, _bOffset) (0x80 + (8*_bEnd) + _bOffset)
+
+/*
-+ * assumes pHub to be locked!
-+ * @requires spin_lock(pHub->Lock)
++ * MUSBHDRC Register bit masks
+ */
-+static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb)
-+{
-+ pHub->bIsChanged = FALSE;
+
-+ pUrb->actual_length=mgc_rh_port_status(pHub, (uint8_t*)pUrb->transfer_buffer);
-+ if (pUrb->actual_length && pUrb->complete) {
-+ COMPLETE_URB(pUrb, NULL);
-+ }
-+}
++/* POWER */
+
-+/**
-+ * Timer expiration function to complete the interrupt URB on changes
-+ * @param ptr standard expiration param (hub pointer)
-+ */
-+static void MGC_VirtualHubTimerExpired(unsigned long ptr)
-+{
-+ struct urb* pUrb;
-+ MGC_VirtualHub* pHub = (MGC_VirtualHub*)ptr;
-+
-+ DBG(2, "<== pHub=%p, pHub->pUrb=%p, pUrb->hcpriv=%p\n", pHub,
-+ pHub->pUrb, (pHub->pUrb)?((struct urb*)pHub->pUrb)->hcpriv:NULL);
-+
-+ spin_lock(&pHub->Lock);
-+ pUrb=pHub->pUrb;
-+ if(pUrb && (pUrb->hcpriv == pHub)) {
-+ uint8_t bPort;
-+
-+ for(bPort = 0; bPort < pHub->bPortCount; bPort++) {
-+ if ( pHub->aPortStatusChange[bPort].wChange ) {
-+ pUrb->status=0;
-+ MGC_VirtualHubCompleteIrq(pHub, pUrb);
-+ break;
-+ }
-+ }
++#define MGC_M_POWER_ISOUPDATE 0x80
++#define MGC_M_POWER_SOFTCONN 0x40
++#define MGC_M_POWER_HSENAB 0x20
++#define MGC_M_POWER_HSMODE 0x10
++#define MGC_M_POWER_RESET 0x08
++#define MGC_M_POWER_RESUME 0x04
++#define MGC_M_POWER_SUSPENDM 0x02
++#define MGC_M_POWER_ENSUSPEND 0x01
++
++/* INTRUSB */
++#define MGC_M_INTR_SUSPEND 0x01
++#define MGC_M_INTR_RESUME 0x02
++#define MGC_M_INTR_RESET 0x04
++#define MGC_M_INTR_BABBLE 0x04
++#define MGC_M_INTR_SOF 0x08
++#define MGC_M_INTR_CONNECT 0x10
++#define MGC_M_INTR_DISCONNECT 0x20
++#define MGC_M_INTR_SESSREQ 0x40
++#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */
++#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
++
++/* DEVCTL */
++#define MGC_M_DEVCTL_BDEVICE 0x80
++#define MGC_M_DEVCTL_FSDEV 0x40
++#define MGC_M_DEVCTL_LSDEV 0x20
++#define MGC_M_DEVCTL_VBUS 0x18
++#define MGC_S_DEVCTL_VBUS 3
++#define MGC_M_DEVCTL_HM 0x04
++#define MGC_M_DEVCTL_HR 0x02
++#define MGC_M_DEVCTL_SESSION 0x01
++
++/* TESTMODE */
++
++#define MGC_M_TEST_FORCE_HOST 0x80
++#define MGC_M_TEST_FIFO_ACCESS 0x40
++#define MGC_M_TEST_FORCE_FS 0x20
++#define MGC_M_TEST_FORCE_HS 0x10
++#define MGC_M_TEST_PACKET 0x08
++#define MGC_M_TEST_K 0x04
++#define MGC_M_TEST_J 0x02
++#define MGC_M_TEST_SE0_NAK 0x01
+
-+ /* re-activate timer only when the urb is still mine; pUrb->hcpriv is
-+ * set to NULL on port disconnect */
-+ MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired,
-+ pHub->wInterval);
-+ } else {
-+ DBG(3, "pUrb=%p, for me =%d\n", pUrb, (pUrb)?((pUrb->hcpriv)?1:0):-1 );
-+ }
-+ spin_unlock(&pHub->Lock);
-+}
++/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
++#define MGC_M_FIFOSZ_DPB 0x10
++/* allocation size (8, 16, 32, ... 4096) */
++#define MGC_M_FIFOSZ_SIZE 0x0f
+
-+/**
-+ * Initialize the virtual hub.
-+ * @param pHub
-+ * @param pBus
-+ * @param bPortCount
-+ * @param pPortServices
-+ * @return 0 success, <0 when errror
-+ */
-+int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus,
-+ uint8_t bPortCount, MGC_PortServices* pPortServices)
-+{
-+ uint8_t bPort;
-+
-+ if(bPortCount > MGC_VIRTUALHUB_MAX_PORTS) {
-+ ERR("Cannot allocate a %d-port device (too many ports)", bPortCount);
-+ return -EINVAL;
-+ }
++/* CSR0 */
++#define MGC_M_CSR0_FLUSHFIFO 0x0100
++#define MGC_M_CSR0_TXPKTRDY 0x0002
++#define MGC_M_CSR0_RXPKTRDY 0x0001
+
-+#if defined(MUSB_REGISTER_ROOT_HUB) || !defined(MUSB_USE_HCD_DRIVER)
-+ /* allocate device, the hcd driver allocate */
-+ pHub->pDevice=USB_ALLOC_DEV(NULL, pBus, 0);
-+ if(!pHub->pDevice) {
-+ ERR("Cannot allocate a %d-port device", bPortCount);
-+ return -ENODEV;
-+ }
-+
-+ pHub->pDevice->speed=USB_SPEED_HIGH;
-+#endif
++/* CSR0 in Peripheral mode */
++#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
++#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
++#define MGC_M_CSR0_P_SENDSTALL 0x0020
++#define MGC_M_CSR0_P_SETUPEND 0x0010
++#define MGC_M_CSR0_P_DATAEND 0x0008
++#define MGC_M_CSR0_P_SENTSTALL 0x0004
+
-+ DBG(3, "New device (%d-port virtual hub) @%#lx allocated\n", \
-+ bPortCount, (unsigned long)pHub->pDevice);
++/* CSR0 in Host mode */
++#define MGC_M_CSR0_H_NO_PING 0x0800
++#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */
++#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */
++#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080
++#define MGC_M_CSR0_H_STATUSPKT 0x0040
++#define MGC_M_CSR0_H_REQPKT 0x0020
++#define MGC_M_CSR0_H_ERROR 0x0010
++#define MGC_M_CSR0_H_SETUPPKT 0x0008
++#define MGC_M_CSR0_H_RXSTALL 0x0004
+
-+ pHub->pBus = pBus;
-+
-+ spin_lock_init(&pHub->Lock);
-+ pHub->pUrb = NULL;
-+ pHub->pPortServices = pPortServices;
-+ pHub->bPortCount = bPortCount;
-+ pHub->bIsChanged = FALSE;
-+ init_timer(&(pHub->Timer)); /* I will need this later */
++/* TxType/RxType */
++#define MGC_M_TYPE_SPEED 0xc0
++#define MGC_S_TYPE_SPEED 6
++#define MGC_TYPE_SPEED_HIGH 1
++#define MGC_TYPE_SPEED_FULL 2
++#define MGC_TYPE_SPEED_LOW 3
++#define MGC_M_TYPE_PROTO 0x30
++#define MGC_S_TYPE_PROTO 4
++#define MGC_M_TYPE_REMOTE_END 0xf
+
-+ for(bPort = 0; bPort < bPortCount; bPort++) {
-+ pHub->aPortStatusChange[bPort].wStatus = 0;
-+ pHub->aPortStatusChange[bPort].wChange = 0;
-+ }
++/* CONFIGDATA */
+
-+#ifdef MUSB_V24
-+ usb_connect(pHub->pDevice);
-+#endif
++#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */
++#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */
++#define MGC_M_CONFIGDATA_BIGENDIAN 0x20
++#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */
++#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */
++#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */
++#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */
++#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* data width 0 => 8bits, 1 => 16bits */
+
-+ return 0; /* OK */
-+}
++/* TXCSR in Peripheral and Host mode */
+
-+/**
-+ * Destroy a virtual hub
-+ * @param pHub the vhub to destroy
-+ */
-+void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub)
-+{
-+#ifdef MUSB_USE_HCD_DRIVER
-+ ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
-+}
++#define MGC_M_TXCSR_AUTOSET 0x8000
++#define MGC_M_TXCSR_ISO 0x4000
++#define MGC_M_TXCSR_MODE 0x2000
++#define MGC_M_TXCSR_DMAENAB 0x1000
++#define MGC_M_TXCSR_FRCDATATOG 0x0800
++#define MGC_M_TXCSR_DMAMODE 0x0400
++#define MGC_M_TXCSR_CLRDATATOG 0x0040
++#define MGC_M_TXCSR_FLUSHFIFO 0x0008
++#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
++#define MGC_M_TXCSR_TXPKTRDY 0x0001
+
-+/**
-+ * Start a virtual hub. Set the address and create a new device for it.
-+ * @param pHub the vhub to start.
-+ */
-+void MGC_VirtualHubStart(MGC_VirtualHub* pHub)
-+{
-+ DBG(2, "<== announcing pHub=%p to usbcore\n", pHub);
-+ pHub->bAddress=1;
-+
-+#ifdef MUSB_REGISTER_ROOT_HUB
-+#ifndef MUSB_USE_HCD_DRIVER
-+ if ( USB_NEW_DEVICE(pHub) ) {
-+ ERR("usb_new_device failed\n");
-+ }
-+#endif
-+#endif
++/* TXCSR in Peripheral mode */
+
-+ DBG(2, "==>\n");
-+}
++#define MGC_M_TXCSR_P_INCOMPTX 0x0080
++#define MGC_M_TXCSR_P_SENTSTALL 0x0020
++#define MGC_M_TXCSR_P_SENDSTALL 0x0010
++#define MGC_M_TXCSR_P_UNDERRUN 0x0004
+
-+/**
-+ * Stop a virtual hub.
-+ * @param pHub the vhub to stop
-+ */
-+void MGC_VirtualHubStop(MGC_VirtualHub* pHub)
-+{
-+#ifndef MUSB_USE_HCD_DRIVER
-+ /* stop interrupt timer */
-+ del_timer_sync(&pHub->Timer);
-+#endif
-+}
++/* TXCSR in Host mode */
+
-+/** Submit an URB to the virtual hub.
-+ * bRequest:
-+ * 00
-+ * 01
-+ * 03
-+ *
-+ * bmRequestType:
-+ * 0x23
-+ * 0xa3
-+ *
-+ * @param pHub the hub urb should be submitted to
-+ * @param pUrb the urb to submit
-+ */
-+int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb)
-+{
-+ uint8_t bRecip; /* from standard request */
-+ uint8_t bReqType; /* from standard request */
-+ uint8_t bType; /* requested descriptor type */
-+ uint16_t wValue; /* from standard request */
-+ uint16_t wIndex; /* from standard request */
-+ uint16_t wLength; /* from standard request */
-+ uint8_t bPort;
-+ const MUSB_DeviceRequest* pRequest;
-+ uint16_t wSize = 0xffff;
-+ uint8_t* pData = (uint8_t*)pUrb->transfer_buffer;
-+ unsigned int pipe = pUrb->pipe;
++#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200
++#define MGC_M_TXCSR_H_DATATOGGLE 0x0100
++#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080
++#define MGC_M_TXCSR_H_RXSTALL 0x0020
++#define MGC_M_TXCSR_H_ERROR 0x0004
+
-+ DBG(-1, "<== pUrb=%p\n", pUrb);
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
-+
-+ spin_lock(&pHub->Lock);
-+ usb_get_urb(pUrb);
-+
-+ pUrb->hcpriv = pHub;
-+ pUrb->status = -EINPROGRESS;
-+
-+ if ( usb_pipeint(pipe) ) {
-+ DBG(-1, "pUrb=%p is periodic status/change event\n", pUrb );
-+
-+ /* this is the one for periodic status/change events */
-+ pHub->pUrb = pUrb;
-+ pHub->wInterval = (pUrb->interval < 16) ? (1 << (pUrb->interval - 1)) :
-+ pUrb->interval;
-+ spin_unlock(&pHub->Lock);
-+ return 0;
-+ }
++/* RXCSR in Peripheral and Host mode */
+
-+ /* handle hub requests/commands */
-+ pRequest = (const MUSB_DeviceRequest*)pUrb->setup_packet;
-+ bReqType = pRequest->bmRequestType & USB_TYPE_MASK;
-+ bRecip = pRequest->bmRequestType & USB_RECIP_MASK;
-+ wValue = le16_to_cpu(pRequest->wValue);
-+ wIndex = le16_to_cpu(pRequest->wIndex);
-+ wLength = le16_to_cpu(pRequest->wLength);
++#define MGC_M_RXCSR_AUTOCLEAR 0x8000
++#define MGC_M_RXCSR_DMAENAB 0x2000
++#define MGC_M_RXCSR_DISNYET 0x1000
++#define MGC_M_RXCSR_DMAMODE 0x0800
++#define MGC_M_RXCSR_INCOMPRX 0x0100
++#define MGC_M_RXCSR_CLRDATATOG 0x0080
++#define MGC_M_RXCSR_FLUSHFIFO 0x0010
++#define MGC_M_RXCSR_DATAERROR 0x0008
++#define MGC_M_RXCSR_FIFOFULL 0x0002
++#define MGC_M_RXCSR_RXPKTRDY 0x0001
+
-+ DBG(3, "pRequest->bRequest=%02x, pRequest->bmRequestType=%02x, wLength=%04x\n",
-+ pRequest->bRequest, pRequest->bmRequestType, wLength);
++/* RXCSR in Peripheral mode */
+
-+ switch (pRequest->bRequest) {
-+ case USB_REQ_GET_STATUS:
-+ DBG(3, "GET_STATUS(), bType=%02x, bRecip=%02x, wIndex=%04x\n", \
-+ bReqType, bRecip, wIndex);
-+
-+ if(USB_TYPE_STANDARD == bReqType) {
-+ /* self-powered */
-+ pData[0] = (USB_RECIP_DEVICE == bRecip) ? 1 : 0;
-+ pData[1] = 0;
-+ wSize = 2;
-+ } else if(USB_TYPE_CLASS == bReqType) {
-+ if((USB_RECIP_OTHER == bRecip) && (wIndex <= pHub->bPortCount)) {
-+ /* port status/change report */
-+ memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2);
-+ memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange),
-+ 2);
-+
-+ /* reset change (TODO: lock) */
-+ pHub->aPortStatusChange[wIndex-1].wChange = 0;
-+ wSize = 4;
-+ } else {
-+ /* hub status */
-+ memset(pData, 0, 4);
-+ wSize = 4;
-+ }
-+
-+ DBG(2, "status report=%02x%02x%02x%02x\n", \
-+ pData[0], pData[1], pData[2], pData[3]);
-+ }
-+ break;
-+
-+ case USB_REQ_CLEAR_FEATURE:
-+ bPort = (uint8_t)(wIndex & 0xff) - 1;
-+ DBG(3, "CLR_FEAT bReqType=0x%x, wValue=0x%x, wIndex=0x%x\n",
-+ bReqType, wValue, (wIndex & 0xff) );
-+ if((USB_TYPE_STANDARD == bReqType) && (USB_RECIP_ENDPOINT == bRecip))
-+ {
-+ wSize = 0;
-+ DBG(3, "END POINT FEATURE!\n");
-+ } else if(USB_TYPE_CLASS == bReqType) {
-+
-+ if(USB_RECIP_OTHER == bRecip)
-+ {
-+ bPort = (uint8_t)(wIndex & 0xff) - 1;
-+ DBG(3, "CLEAR_PORT_FEATURE(%d), port %d\n", \
-+ wValue, bPort);
-+ switch(wValue) {
-+ case USB_PORT_FEAT_CONNECTION:
-+ case USB_PORT_FEAT_OVER_CURRENT:
-+ case USB_PORT_FEAT_POWER:
-+ case USB_PORT_FEAT_LOWSPEED:
-+ case USB_PORT_FEAT_HIGHSPEED:
-+ case USB_PORT_FEAT_TEST:
-+ case USB_PORT_FEAT_INDICATOR:
-+ DBG(3, "feat 0x%02x, wIndex=%d\n", wValue, bPort);
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_ENABLE:
-+ DBG(4, "enable port %d\n", bPort);
-+ pHub->pPortServices->pfSetPortEnable(
-+ pHub->pPortServices->pPrivateData, bPort, FALSE);
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_SUSPEND:
-+ DBG(3, "suspend port %d\n", bPort);
-+ pHub->pPortServices->pfSetPortSuspend(
-+ pHub->pPortServices->pPrivateData, bPort, FALSE);
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_RESET:
-+ DBG(4, "reset port %d\n", bPort);
-+ pHub->pPortServices->pfSetPortReset(
-+ pHub->pPortServices->pPrivateData, bPort, FALSE);
-+ wSize = 0;
-+ break;
-+
-+ /* acknowledge changes: */
-+ case USB_PORT_FEAT_C_CONNECTION:
-+ DBG(3, "ack connection port %d\n", bPort);
-+ pHub->aPortStatusChange[bPort].wChange &= ~1;
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_C_ENABLE:
-+ DBG(3, "ack enable port %d\n", bPort);
-+ pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE;
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_C_SUSPEND:
-+ DBG(3, "ack suspend port %d\n", bPort);
-+
-+ pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND;
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_C_RESET:
-+ DBG(3, "ack reset port %d\n", bPort);
-+ pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET;
-+ wSize = 0;
-+ break;
-+ case USB_PORT_FEAT_C_OVER_CURRENT:
-+ DBG(3, "ack over current port %d\n", bPort);
-+ wSize = 0;
-+ break;
-+
-+ default:
-+ INFO("clear feature 0x%02x on port=%d unknown\n", wValue, bPort);
-+ break;
-+ }
-+ } else {
-+ DBG(3, "clear wValue=%d on port=%d\n", wValue, bPort);
-+ switch(wValue) {
-+ case C_HUB_LOCAL_POWER:
-+ case C_HUB_OVER_CURRENT:
-+ wSize = 0;
-+ break;
-+ }
-+ }
-+ pHub->bIsChanged = TRUE;
-+ }
-+ break;
-+
-+ case USB_REQ_SET_FEATURE:
-+ if((USB_TYPE_CLASS == bReqType) && (USB_RECIP_OTHER == bRecip))
-+ {
-+ bPort = (uint8_t)(wIndex & 0xff) - 1;
-+ DBG(3, "SET_PORT_FEATURE(0x%02x), port %d\n", wValue, bPort);
-+ switch(wValue) {
-+ case USB_PORT_FEAT_SUSPEND:
-+ DBG(3, "suspend port %d\n", bPort);
-+ pHub->pPortServices->pfSetPortSuspend(
-+ pHub->pPortServices->pPrivateData, bPort, TRUE);
-+ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND;
-+ pHub->bIsChanged = TRUE;
-+ wSize = 0;
-+ break;
-+
-+ case USB_PORT_FEAT_RESET:
-+ DBG(3, "reset port %d\n", bPort);
-+ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET;
-+ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
-+ pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET;
-+ pHub->bIsChanged = TRUE;
-+ pHub->pPortServices->pfSetPortReset(pHub->pPortServices->pPrivateData,
-+ bPort, TRUE);
-+ wSize = 0;
-+ break;
-+
-+ case USB_PORT_FEAT_POWER:
-+ DBG(3, "power port %d\n", bPort);
-+ pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData,
-+ bPort, TRUE);
-+ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER;
-+ wSize = 0;
-+ break;
-+
-+ case USB_PORT_FEAT_ENABLE:
-+ DBG(3, "enable port %d\n", bPort);
-+ pHub->pPortServices->pfSetPortEnable(pHub->pPortServices->pPrivateData,
-+ bPort, TRUE);
-+ pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
-+ wSize = 0;
-+ break;
-+ }
-+ } else {
-+ DBG(3, "SET_FEATURE(%04x), but feature unknown\n", wValue);
-+ }
-+ break;
-+
-+ case USB_REQ_SET_ADDRESS:
-+ pHub->bAddress = (wValue & 0x7f);
-+ DBG(3, "SET_ADDRESS(%x) \n", pHub->bAddress);
-+ wSize = 0;
-+ break;
-+
-+ case USB_REQ_GET_DESCRIPTOR:
-+ if(USB_TYPE_CLASS == bReqType) {
-+ DBG(3, "GET_CLASS_DESCRIPTOR()\n");
-+
-+ pData[0] = 9;
-+ pData[1] = 0x29;
-+ pData[2] = pHub->bPortCount;
-+ /* min characteristics */
-+ pData[3] = 1; /* invidual port power switching */
-+ pData[4] = 0;
-+ /* PowerOn2PowerGood */
-+ pData[5] = 50;
-+ /* no current */
-+ pData[6] = 0;
-+ /* removable ports */
-+ pData[7] = 0;
-+ /* reserved */
-+ pData[8] = 0xff;
-+ wSize = pData[0];
-+ } else {
-+ bType = (uint8_t)(wValue >> 8);
-+ DBG(3, "GET_DESCRIPTOR(%d)\n", bType);
-+ switch(bType) {
-+ case USB_DT_DEVICE: /* 1 */
-+ wSize = min(wLength, (uint16_t)MGC_aVirtualHubDeviceDesc[0]);
-+ memcpy(pData, MGC_aVirtualHubDeviceDesc, wSize);
-+ break;
-+ case USB_DT_DEVICE_QUALIFIER:
-+ wSize = min(wLength, (uint16_t)MGC_aVirtualHubQualifierDesc[0]);
-+ memcpy(pData, MGC_aVirtualHubQualifierDesc, wSize);
-+ break;
-+ case USB_DT_CONFIG: /* 2 */
-+ wSize = min(wLength, (uint16_t)MGC_VirtualHubConfigDesc[2]);
-+ memcpy(pData, MGC_VirtualHubConfigDesc, wSize);
-+ break;
-+ case USB_DT_OTHER_SPEED:
-+ wSize = min(wLength, (uint16_t)MGC_VirtualHubOtherConfigDesc[2]);
-+ memcpy(pData, MGC_VirtualHubOtherConfigDesc, wSize);
-+ break;
-+ }
-+ }
-+ break;
-+
-+ case USB_REQ_GET_CONFIGURATION:
-+ DBG(3, "GET_CONFIG() => 1\n");
-+ pData[0] = 1;
-+ wSize = 1;
-+ break;
-+
-+ case USB_REQ_SET_CONFIGURATION:
-+ DBG(3, "SET_CONFIG(%04x)\n", wValue);
-+ wSize = 0;
-+ break;
-+
-+ } /* END: switch on request type */
++#define MGC_M_RXCSR_P_ISO 0x4000
++#define MGC_M_RXCSR_P_SENTSTALL 0x0040
++#define MGC_M_RXCSR_P_SENDSTALL 0x0020
++#define MGC_M_RXCSR_P_OVERRUN 0x0004
+
-+ if(0xffff == wSize) {
-+ pUrb->status = USB_ST_STALL;
-+ } else {
-+ pUrb->actual_length = wSize;
-+ pUrb->status = 0;
-+ }
-+
-+ spin_unlock(&pHub->Lock);
-+ if (pUrb->complete) {
-+ DBG(3, "completing URB status=%d\n", pUrb->status );
-+ COMPLETE_URB(pUrb, NULL);
-+ pUrb->hcpriv = NULL;
-+ usb_put_urb(pUrb);
-+ DBG(4, "URB completed\n");
-+ }
++/* RXCSR in Host mode */
+
-+ DBG(2, "==> pUrb->status=%d %s, length=%d, completed=%s\n", pUrb->status, \
-+ (pUrb->status)?"(STALL)":"", pUrb->actual_length,
-+ (pUrb->complete)?"yes":"no");
-+
-+ return 0;
-+}
++#define MGC_M_RXCSR_H_AUTOREQ 0x4000
++#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400
++#define MGC_M_RXCSR_H_DATATOGGLE 0x0200
++#define MGC_M_RXCSR_H_RXSTALL 0x0040
++#define MGC_M_RXCSR_H_REQPKT 0x0020
++#define MGC_M_RXCSR_H_ERROR 0x0004
+
-+/**
-+ * Unlink an URB from a virtual hub.
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param pUrb URB pointer
-+ * @return Linux status code
-+ * @see #MGC_VirtualHubInit
-+ */
-+int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb)
-+{
-+ DBG(2, "<== pUrb=%p\n", pUrb);
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+ ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
++/* HUBADDR */
++#define MGC_M_HUBADDR_MULTI_TT 0x80
+
-+ spin_lock(&pHub->Lock);
-+ if(pUrb && (pHub->pUrb == pUrb) && (pUrb->hcpriv == pHub)) {
-+ pHub->bIsChanged = FALSE;
-+
-+ if (pUrb->transfer_flags & USB_ASYNC_UNLINK) {
-+ pUrb->status = -ECONNRESET;
-+ if (pUrb->complete) {
-+ COMPLETE_URB(pUrb, NULL);
-+ }
-+ } else {
-+ pUrb->status = -ENOENT;
-+ }
+
-+ pUrb->hcpriv = NULL;
-+ pHub->pUrb = NULL;
-+ }
-+
-+ spin_unlock(&pHub->Lock);
-+ usb_put_urb(pUrb);
++/* TXCSR in Peripheral and Host mode */
+
-+ DBG(2, "==>\n");
-+ return 0;
-+}
++#define MGC_M_TXCSR2_AUTOSET 0x80
++#define MGC_M_TXCSR2_ISO 0x40
++#define MGC_M_TXCSR2_MODE 0x20
++#define MGC_M_TXCSR2_DMAENAB 0x10
++#define MGC_M_TXCSR2_FRCDATATOG 0x08
++#define MGC_M_TXCSR2_DMAMODE 0x04
+
++#define MGC_M_TXCSR1_CLRDATATOG 0x40
++#define MGC_M_TXCSR1_FLUSHFIFO 0x08
++#define MGC_M_TXCSR1_FIFONOTEMPTY 0x02
++#define MGC_M_TXCSR1_TXPKTRDY 0x01
+
-+/**
-+ * assumes bPortIndex < MGC_VIRTUALHUB_MAX_PORTS
-+ * AND pHub->Lock to be... locked :)
-+ */
-+STATIC void MGC_SetVirtualHubPortSpeed(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex, uint8_t bSpeed
-+) {
-+ uint16_t wSpeedMask = 0;
++/* TXCSR in Peripheral mode */
+
-+ DBG(2, "<== bPortIndex=%d, bSpeed=%d\n", bPortIndex, bSpeed);
-+
-+ switch(bSpeed) {
-+ case 0:
-+ wSpeedMask = USB_PORT_STAT_LOW_SPEED;
-+ break;
-+ case 2:
-+ wSpeedMask = USB_PORT_STAT_HIGH_SPEED;
-+ break;
-+ }
++#define MGC_M_TXCSR1_P_INCOMPTX 0x80
++#define MGC_M_TXCSR1_P_SENTSTALL 0x20
++#define MGC_M_TXCSR1_P_SENDSTALL 0x10
++#define MGC_M_TXCSR1_P_UNDERRUN 0x04
+
-+ pHub->aPortStatusChange[bPortIndex].wStatus &=
-+ ~(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
-+ pHub->aPortStatusChange[bPortIndex].wStatus |= 1 | wSpeedMask;
-+ pHub->bIsChanged = TRUE;
-+ DBG(2, "==>\n");
-+}
++/* TXCSR in Host mode */
+
-+/**
-+ * A port reset is complete
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, uint8_t bPortIndex,
-+ uint8_t bHubSpeed)
-+{
-+ DBG(2, "<==port %d reset complete\n", bPortIndex);
-+
-+ if(bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) {
-+ MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bHubSpeed);
-+
-+ pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_RESET;
-+ pHub->aPortStatusChange[bPortIndex].wStatus |= USB_PORT_STAT_ENABLE;
-+ pHub->aPortStatusChange[bPortIndex].wChange = USB_PORT_STAT_RESET |
-+ USB_PORT_STAT_ENABLE;
-+ pHub->bIsChanged = TRUE;
-+ }
-+ DBG(2, "==>\n");
-+}
++#define MGC_M_TXCSR1_H_NAKTIMEOUT 0x80
++#define MGC_M_TXCSR1_H_RXSTALL 0x20
++#define MGC_M_TXCSR1_H_ERROR 0x04
+
-+/**
-+ * A device has effectively been connected to a virtual hub port
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port with connected device
-+ * @param bSpeed device speed (0=>low, 1=>full, 2=>high)
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, uint8_t bPortIndex,
-+ uint8_t bSpeed)
-+{
-+ DBG(2, "<== port %d connected, core reports speed=%d\n", bPortIndex, bSpeed);
-+ if (bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) {
-+ struct urb* pUrb=pHub->pUrb;
-+
-+ MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bSpeed);
-+ pHub->aPortStatusChange[bPortIndex].wChange |= 1;
-+
-+ /* shorter time... it want it NOW! */
-+ DBG(2, "<== pHub=%p, pHub->pUrb=%p, pHub->pUrb->hcpriv=%p\n", pHub,
-+ pUrb, (pUrb)?pUrb->hcpriv:NULL);
-+ if ( pUrb && ( (!pUrb->hcpriv) || (pUrb->hcpriv== pHub))) {
-+ pUrb->hcpriv=pHub;
-+ MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired, 1);
-+ }
-+ }
-+ DBG(2, "==>\n");
-+}
-+
-+/**
-+ * A device has effectively been disconnected from a virtual hub port
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port of disconnected device
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, uint8_t bPortIndex)
-+{
-+ struct urb* pUrb;
++/* RXCSR in Peripheral and Host mode */
+
-+ DBG(-1, "<== Port %d disconnected\n", bPortIndex);
-+
-+ if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) {
-+ DBG(-1, "==>");
-+ return;
-+ }
-+
-+#ifndef MUSB_USE_HCD_DRIVER
-+ del_timer_sync(&pHub->Timer);
-+#endif
++#define MGC_M_RXCSR2_AUTOCLEAR 0x80
++#define MGC_M_RXCSR2_DMAENAB 0x20
++#define MGC_M_RXCSR2_DISNYET 0x10
++#define MGC_M_RXCSR2_DMAMODE 0x08
++#define MGC_M_RXCSR2_INCOMPRX 0x01
+
-+ pUrb= pHub->pUrb;
-+ pHub->aPortStatusChange[bPortIndex].wStatus &= ~1;
-+ pHub->aPortStatusChange[bPortIndex].wChange |= 1;
-+ pHub->bIsChanged = TRUE;
-+
-+ if (pUrb && (pUrb->hcpriv == pHub)) {
-+ pUrb->status=0;
-+ MGC_VirtualHubCompleteIrq(pHub, pUrb);
-+ }
++#define MGC_M_RXCSR1_CLRDATATOG 0x80
++#define MGC_M_RXCSR1_FLUSHFIFO 0x10
++#define MGC_M_RXCSR1_DATAERROR 0x08
++#define MGC_M_RXCSR1_FIFOFULL 0x02
++#define MGC_M_RXCSR1_RXPKTRDY 0x01
+
-+ DBG(-1, "==>\n");
-+}
-+
-+/**
-+ * A device has effectively resumed a virtual hub port
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port of resume
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, uint8_t bPortIndex)
-+{
-+ DBG(2, "<== Resume port %d\n", bPortIndex);
-+#ifdef MUSB_USE_HCD_DRIVER
-+ ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
++/* RXCSR in Peripheral mode */
+
-+ if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) {
-+ return;
-+ }
++#define MGC_M_RXCSR2_P_ISO 0x40
++#define MGC_M_RXCSR1_P_SENTSTALL 0x40
++#define MGC_M_RXCSR1_P_SENDSTALL 0x20
++#define MGC_M_RXCSR1_P_OVERRUN 0x04
+
-+ pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_SUSPEND;
-+ pHub->aPortStatusChange[bPortIndex].wChange |= USB_PORT_STAT_SUSPEND;
-+ pHub->bIsChanged = TRUE;
-+ DBG(2, "==>\n");
-+}
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.h
---- linux-2.6.20/drivers/usb/nomadik/musb_virthub.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.h 2008-07-28 15:21:05.000000000 +0530
-@@ -0,0 +1,240 @@
++/* RXCSR in Host mode */
++
++#define MGC_M_RXCSR2_H_AUTOREQ 0x40
++#define MGC_M_RXCSR1_H_RXSTALL 0x40
++#define MGC_M_RXCSR1_H_REQPKT 0x20
++#define MGC_M_RXCSR1_H_ERROR 0x04
++
++/* Top control register */
++#define MGC_M_TOPCTRL_MODE_ULPI 0x09
++#define MGC_M_TOPCTRL_MODE_SRST 0x04
++
++#endif /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musbhsfc.h
+@@ -0,0 +1,150 @@
+/*
-+ * linux/drivers/usb/nomadik/musb_virthub.h
++ * linux/drivers/usb/nomadik/musbhsfc.h
+ *
+ * Copyright 2007, STMicroelectronics
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
-+#ifndef __MUSB_LINUX_VIRTUALHUB_H__
-+#define __MUSB_LINUX_VIRTUALHUB_H__
-+
-+#include <linux/spinlock.h>
-+#include <linux/timer.h>
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
-+#define USB_NEW_DEVICE(_vh) usb_register_root_hub((_vh)->pDevice, (_vh)->pBus->controller)
-+#else
-+#ifdef __bluecat__
-+#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice, (((_vh)->pDevice)->parent)?&((_vh)->pDevice)->parent->dev:NULL )
-+#else
-+#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice)
-+#endif
-+#endif
++#ifndef __MUSB_HSFC_DEFS_H__
++#define __MUSB_HSFC_DEFS_H__
+
-+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
-+#define MUSB_REGISTER_ROOT_HUB
-+#endif
++#define MGC_MAX_USB_ENDS 16
+
-+struct urb;
-+struct usb_bus;
++#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */
+
-+#ifdef MUSB_USE_HCD_DRIVER
-+struct usb_hcd;
-+#endif
++#define MGC_M_FIFO_EP0 0x20
+
-+/**
-+ * Introduction.
-+ * For USB controllers lacking embedded root hubs,
-+ * this module can be used as a virtual root hub,
-+ * with one or more controllers as the virtual hub's ports.
++/*
++ * MUSBHSFC Register map
+ */
+
-+/****************************** CONSTANTS ********************************/
++/* Common USB registers */
+
-+/** Maximum number of ports to accomodate */
-+#define MGC_VIRTUALHUB_MAX_PORTS 7
++#define MGC_O_HSFC_FADDR 0x00 /* 8-bit */
++#define MGC_O_HSFC_POWER 0x01 /* 8-bit */
+
-+/******************************** TYPES **********************************/
++#define MGC_O_HSFC_INTRIN 0x02 /* 16-bit */
++#define MGC_O_HSFC_INTROUT 0x04
++#define MGC_O_HSFC_INTRINE 0x06
++#define MGC_O_HSFC_INTROUTE 0x08
++#define MGC_O_HSFC_INTRUSB 0x0A /* 8 bit */
++#define MGC_O_HSFC_INTRUSBE 0x0B /* 8 bit */
++#define MGC_O_HSFC_FRAME 0x0C
++#define MGC_O_HSFC_INDEX 0x0E /* 8 bit */
++#define MGC_O_HSFC_TESTMODE 0x0F /* 8 bit */
+
-+/**
-+ * Set a port's power on or off.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bPower TRUE to power on the port; FALSE to power off
-+ */
-+typedef void (*MGC_pfSetPortPower)(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bPower);
++/* These are actually indexed: */
++#define MGC_O_HSFC_TXFIFOSZ 0x1a /* 8-bit (see masks) */
++#define MGC_O_HSFC_RXFIFOSZ 0x1b /* 8-bit (see masks) */
++#define MGC_O_HSFC_TXFIFOADD 0x1c /* 16-bit offset shifted right 3 */
++#define MGC_O_HSFC_RXFIFOADD 0x1e /* 16-bit offset shifted right 3 */
+
-+/**
-+ * Enable or disable a port.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bEnable TRUE to enable port; FALSE to disable
-+ */
-+typedef void (*MGC_pfSetPortEnable)(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bEnable);
++/* Endpoint registers */
++#define MGC_O_HSFC_TXMAXP 0x00
++#define MGC_O_HSFC_TXCSR 0x02
++#define MGC_O_HSFC_CSR0 MGC_O_HSFC_TXCSR /* re-used for EP0 */
++#define MGC_O_HSFC_RXMAXP 0x04
++#define MGC_O_HSFC_RXCSR 0x06
++#define MGC_O_HSFC_RXCOUNT 0x08
++#define MGC_O_HSFC_COUNT0 MGC_O_HSFC_RXCOUNT /* re-used for EP0 */
+
-+/**
-+ * Set a port's suspend mode on or off.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bSuspend TRUE to suspend port; FALSE to resume
++/*
++ * MUSBHSFC Register bit masks
+ */
-+typedef void (*MGC_pfSetPortSuspend)(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bSuspend);
+
-+/**
-+ * Set a port's reset on or off.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bReset TRUE to assert reset on the bus behind a port; FALSE to deassert
-+ */
-+typedef void (*MGC_pfSetPortReset)(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bReset);
-+
-+/**
-+ * MGC_PortServices.
-+ * Services provided to a virtual by a USB port controller.
-+ * @field pPrivateData port controller's implementation data;
-+ * not to be interpreted by virtual hub
-+ * @param pfSetPortPower set-port-power call
-+ * @param pfSetPortEnable set-port-enable call
-+ * @param pfSetPortSuspend set-port-suspend call
-+ * @param pfSetPortReset set-port-reset call
-+ */
-+typedef struct
-+{
-+ void* pPrivateData;
-+ MGC_pfSetPortPower pfSetPortPower;
-+ MGC_pfSetPortEnable pfSetPortEnable;
-+ MGC_pfSetPortSuspend pfSetPortSuspend;
-+ MGC_pfSetPortReset pfSetPortReset;
-+} MGC_PortServices;
++/* POWER */
+
-+/**
-+ * MGC_HubPortStatusChange.
-+ * @field wStatus status
-+ * @field wChange change
-+ */
-+typedef struct
-+{
-+ uint16_t wStatus;
-+ uint16_t wChange;
-+} MGC_HubPortStatusChange;
++#define MGC_M_POWER_ISOUPDATE 0x80
++#define MGC_M_POWER_SOFTCONN 0x40
++#define MGC_M_POWER_HSENAB 0x20
++#define MGC_M_POWER_HSMODE 0x10
++#define MGC_M_POWER_RESET 0x08
++#define MGC_M_POWER_RESUME 0x04
++#define MGC_M_POWER_SUSPENDM 0x02
++#define MGC_M_POWER_ENSUSPEND 0x01
+
-+/**
-+ * MGC_VirtualHub.
-+ * Virtual USB hub instance data.
-+ * @field Lock spinlock
-+ * @field pBus our bus pointer
-+ * @field pDevice our device pointer
-+ * @field pUrb pointer to interrupt URB for status change
-+ * @field pPortServices pointer to port services
-+ * @field Timer interval timer for status change interrupts
-+ * @field aPortStatusChange status/change array
-+ * @field bPortCount how many ports
-+ * @field wInterval actual interval in milliseconds
-+ * @field bIsChanged TRUE if changes to report
-+ * @field bAddress address assigned by usbcore
-+ */
-+typedef struct
-+{
-+ spinlock_t Lock;
-+ struct usb_bus* pBus;
-+ struct usb_device* pDevice;
++/* Interrupt register bit masks */
++#define MGC_M_INTR_SUSPEND 0x01
++#define MGC_M_INTR_RESUME 0x02
++#define MGC_M_INTR_RESET 0x04
++#define MGC_M_INTR_SOF 0x08
+
-+ void *pUrb;
-+ MGC_PortServices* pPortServices;
-+ struct timer_list Timer;
-+ MGC_HubPortStatusChange aPortStatusChange[MGC_VIRTUALHUB_MAX_PORTS];
-+ uint8_t bPortCount;
-+ uint16_t wInterval;
-+ uint8_t bIsChanged;
-+ uint8_t bAddress;
-+
-+} MGC_VirtualHub;
++/* TESTMODE */
+
-+/******************************** Protos **********************************/
++#define MGC_M_TEST_FORCEFS 0x20
++#define MGC_M_TEST_FORCEHS 0x10
++#define MGC_M_TEST_PACKET 0x08
++#define MGC_M_TEST_K 0x04
++#define MGC_M_TEST_J 0x02
++#define MGC_M_TEST_SE0_NAK 0x01
+
-+extern int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData);
++/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
++#define MGC_M_FIFOSZ_DPB 0x10
++/* allocation size (8, 16, 32, ... 4096) */
++#define MGC_M_FIFOSZ_SIZE 0x0f
+
-+#ifdef MUSB_VIRTHUB
-+void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bPower);
-+void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bEnable);
-+void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bSuspend);
-+void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
-+ uint8_t bReset);
++/* CSR0 */
+
-+extern int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus,
-+ uint8_t bPortCount, MGC_PortServices* pPortServices);
-+extern void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub);
-+extern void MGC_VirtualHubStart(MGC_VirtualHub* pHub);
-+extern void MGC_VirtualHubStop(MGC_VirtualHub* pHub);
-+extern int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
-+extern int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
-+extern void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex, uint8_t bHubSpeed);
-+extern void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex, uint8_t bSpeed);
-+extern void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex);
-+extern void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex);
++#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
++#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
++#define MGC_M_CSR0_P_SENDSTALL 0x0020
++#define MGC_M_CSR0_P_SETUPEND 0x0010
++#define MGC_M_CSR0_P_DATAEND 0x0008
++#define MGC_M_CSR0_P_SENTSTALL 0x0004
++#define MGC_M_CSR0_TXPKTRDY 0x0002
++#define MGC_M_CSR0_RXPKTRDY 0x0001
+
-+#else /* #ifdef MUSB_VIRTHUB */
++/* TXCSR */
+
-+static int uint8_t MGC_VirtualHubInit(MGC_VirtualHub* pHub,
-+ struct usb_bus* pBus, uint8_t bPortCount,
-+ MGC_PortServices* pPortServices)
-+{
-+ DBG(-1, "this should not be called");
-+ return -ENODEV;
-+};
-+static inline void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub) {
-+ DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubStart(MGC_VirtualHub* pHub) {
-+ DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubStop(MGC_VirtualHub* pHub) {
-+ DBG(-1, "this should not be called");
-+};
-+static inline int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb) {
-+ DBG(-1, "this should not be called");
-+ return -ENODEV;
-+};
++#define MGC_M_TXCSR_AUTOSET 0x8000
++#define MGC_M_TXCSR_ISO 0x4000
++#define MGC_M_TXCSR_MODE 0x2000
++#define MGC_M_TXCSR_DMAENAB 0x1000
++#define MGC_M_TXCSR_FRCDATATOG 0x0800
++#define MGC_M_TXCSR_P_INCOMPTX 0x0080
++#define MGC_M_TXCSR_CLRDATATOG 0x0040
++#define MGC_M_TXCSR_P_SENTSTALL 0x0020
++#define MGC_M_TXCSR_P_SENDSTALL 0x0010
++#define MGC_M_TXCSR_FLUSHFIFO 0x0008
++#define MGC_M_TXCSR_P_UNDERRUN 0x0004
++#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
++#define MGC_M_TXCSR_TXPKTRDY 0x0001
+
-+static inline int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb) {
-+ DBG(-1, "this should not be called");
-+ return -ENODEV;
-+};
++/* RXCSR */
+
-+static inline void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex, uint8_t bHubSpeed) {
-+ DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex, uint8_t bSpeed) {
-+ DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub,
-+ uint8_t bPortIndex) {
-+ DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub,
-+uint8_t bPortIndex) {
-+ DBG(-1, "this should not be called");
-+};
++#define MGC_M_RXCSR_AUTOCLEAR 0x8000
++#define MGC_M_RXCSR_P_ISO 0x4000
++#define MGC_M_RXCSR_DMAENAB 0x2000
++#define MGC_M_RXCSR_DISNYET 0x1000
++#define MGC_M_RXCSR_DMAMODE 0x0800
++#define MGC_M_RXCSR_INCOMPRX 0x0100
++#define MGC_M_RXCSR_CLRDATATOG 0x0080
++#define MGC_M_RXCSR_P_SENTSTALL 0x0040
++#define MGC_M_RXCSR_P_SENDSTALL 0x0020
++#define MGC_M_RXCSR_FLUSHFIFO 0x0010
++#define MGC_M_RXCSR_DATAERR 0x0008
++#define MGC_M_RXCSR_P_OVERRUN 0x0004
++#define MGC_M_RXCSR_FIFOFULL 0x0002
++#define MGC_M_RXCSR_RXPKTRDY 0x0001
+
-+#endif
++/*
++ * register access macros
++ */
+
++/* Get offset for a given FIFO */
++#define MGC_FIFO_OFFSET(_bEnd) (MGC_M_FIFO_EP0 + (_bEnd * 4))
+
+#endif /* multiple inclusion protection */
-+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c
---- linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c 2008-09-17 13:23:34.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c
@@ -0,0 +1,2845 @@
+/*
+ * linux/drivers/usb/gadget/nomadik_udc.c
+ *
+ * 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
+ */
+
+
+
+
+/*
-+ * 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
+ * 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.
+ */
+ */
+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);
+}
+
+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);
+}
+
+/**
-+ * Current Frame number will be returned
++ * Current Frame number will be returned
+ * @param gadget the gadget
+ * @return Frame Number
+ */
+ * @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" );
+/**
+ * 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)
+ : 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);
+ 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);
+{
+ u16 num = EP_NUMBER(ep);
+ u8 *base_addr = ( u8 *)udc_base_addr;
-+
++
+ MUSB_SELECTEND(base_addr, num);
+}
+
+ 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)) {
+ return -EDOM;
+ }
+#endif
-+
++
+ /* xfer types must match, except that interrupt ~= bulk */
+ if (ep->bmAttributes != desc->bmAttributes
+ && ep->bmAttributes != USB_ENDPOINT_XFER_BULK
+ ERR( "%s, %s type mismatch\n", __FUNCTION__, _ep->name);
+ return -EINVAL;
+ }
-+
++
+ udc = ep->udc;
+ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
+ ERR( "%s, bogus device state\n", __FUNCTION__);
+ return -ESHUTDOWN;
+ }
-+
-+
++
++
+ ep->desc = desc;
+ ep->maxpacket = ep->ep.maxpacket = maxp;
+ ep->binactive = MUSB_GADGET_EP_ACTIVE;
+ ep->stopped=0;
-+
++
+ if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
+ list_add(&ep->iso, &udc->iso);
-+
++
+ spin_lock_irqsave(&udc->lock, flags);
+ use_ep(ep);
+ if ( desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) {
+ intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE);
+ intr_txe |= (1 <<bEnd);
+ MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
-+
++
+ MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXMAXP, bEnd, desc->wMaxPacketSize);
+ } else {
+ intr_rxe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRRXE);
+ 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);
+ 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);
+ /* 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 */
+ 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;
+ u8 *base_addr = ( u8 *)udc_base_addr;
+ const struct usb_endpoint_descriptor *desc = (const struct usb_endpoint_descriptor *)ep->desc;
+ uint8_t bEnd = EP_NUMBER(ep);
-+
++
+ if (!ep || !ep->desc) {
+ DBG(3, "%s, %s not enabled\n", __FUNCTION__,
+ ep ? ep->ep.name : NULL);
+ return -EINVAL;
+ }
-+
-+
++
++
+ spin_lock_irqsave(&ep->udc->lock, flags);
-+
++
+ if ( desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) {
+ uint16_t intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE);
+ intr_txe&= ~(1 <<bEnd);
-+ MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
++ MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
+ } else {
+ uint16_t intr_rxe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRRXE);
+ intr_rxe&=~(1 <<bEnd);
+ MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRRXE, intr_rxe);
+ }
-+
++
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+ ep->desc = NULL;
+ nuke (ep, -ESHUTDOWN);
+ ep->ep.maxpacket = ep->maxpacket;
+ ep->binactive = MUSB_GADGET_EP_DISABLED;
-+
++
+ if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
+ list_del_init(&ep->iso);
-+
-+
++
++
+ DBG(4,"%s disabled\n", _ep->name);
+ return 0;
+}
+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));
+ req->req.dma = DMA_ADDR_INVALID;
+ INIT_LIST_HEAD(&req->req.list);
+ req->end_number = EP_NUMBER(ep);
-+
++
+ }
+ return &req->req;
+}
+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);
+}
+{
+ void *retval;
+ struct nomadik_ep *ep;
-+
++
+ ep = container_of(_ep, struct nomadik_ep, ep);
+ if (use_dma && ep->has_dma) {
+ static int warned;
+ 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);
+ )
+{
+ 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);
+/*-------------------------------------------------------------------------*/
+
+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)
+{
+ 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 )
+ {
+ 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);
+ 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
+ {
+ 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;
+}
+
+ 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;
+}
+ 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;
+ 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)
+ {
+ 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);
+ 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);
+#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 );
+ 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);
+ 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;
+{
+ 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);
+/**
+ * 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 );
+/**
+ * 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);
+}
+/**
+ * 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;
+}
+ * @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;
+ 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) )
+ {
+ 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]);
+ }
-+
++
+}
+
+/**
+ * @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);
+ }
+
+/**
+ * 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
+ *
+ * @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;
+}
+
+ * @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);
+}
+ 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;
+ 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);
+ 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);
+ }
+ 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");
+ {
+ 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");
+ 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;
+ 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;
+}
+ * 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)
+ 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");
+}
+
+
+/**
+ * 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;
+ struct nomadik_ep* end_ptr = &(dev_context->end[0]);
+ struct usb_request *reqptr=udc_current_request(end_ptr);
+ uint16_t csrval = MUSB_M_CSR0_TXPKTRDY;
-+ uint8_t* fifo_source;
-+ uint8_t fifo_count;
-+
-+ DBG(4, "<==\n");
-+
++ uint8_t* fifo_source;
++ uint8_t fifo_count;
++
++ DBG(4, "<==\n");
++
+#ifdef MUSB_PARANOID
+ if ( !dev_context || !reqptr ) {
-+ ERR("dev_context=%p, reqptr=%p", dev_context, reqptr);
++ ERR("dev_context=%p, reqptr=%p", dev_context, reqptr);
+ return -EINVAL;
+ }
+#endif
-+
-+#ifdef MUSB_PARANOID
-+ ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
-+ ASSERT_SPINLOCK_LOCKED(&end_ptr->lock);
++
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++ ASSERT_SPINLOCK_LOCKED(&end_ptr->lock);
+#endif
-+
++
+ spin_lock_irqsave(&dev_context->lock, flags);
+ MUSB_SELECTEND(base_addr, 0);
-+
++
+ if ( reqptr->actual==0 ) {
+ /* ack the request first */
+ DBG(4, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) );
-+ MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
++ MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
+ MUSB_M_CSR0_P_SVDRXPKTRDY);
+ }
-+
-+ /* load the data */
++
++ /* load the data */
+ fifo_source = (uint8_t*)reqptr->buf+reqptr->actual;
+ fifo_count =min((int)MUSB_END0_FIFOSIZE, (int)(reqptr->length-reqptr->actual));
+ udc_load_fifo(base_addr, 0, fifo_count, fifo_source);
+ reqptr->actual+=fifo_count; /* done */
-+
++
+ /* update the flags */
+ if ( fifo_count < MUSB_MAX_END0_PACKET ) {
+ csrval |= MUSB_M_CSR0_P_DATAEND;
+ reqptr->status=0; /* done */
-+ }
-+
-+ /* send it out! (this will trigger the ep0 completition IRQ)
++ }
++
++ /* send it out! (this will trigger the ep0 completition IRQ)
+ * serviced in interrupt_complete() */
-+ DBG(4, "wrote fifo_count=%d bytes, csrval=%s\n", fifo_count,
++ DBG(4, "wrote fifo_count=%d bytes, csrval=%s\n", fifo_count,
+ decode_csr0(csrval) );
+ MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
+ spin_unlock_irqrestore(&dev_context->lock, flags);
-+
-+ DBG(4, "==>\n");
++
++ DBG(4, "==>\n");
+ return 0;
+}
+
+/**
-+ * Read a FULL header packet from the hardware. The buffer starts with
++ * Read a FULL header packet from the hardware. The buffer starts with
+ * struct usb_ctrlrequest (fields are converted to device specific
+ * byte order).
+ *
+ * @param wcount>0
-+ * @return 0 when the packet is complete, a negative number when an error
++ * @return 0 when the packet is complete, a negative number when an error
+ * occurred, a positive number when still there are bytes to read.
+ */
+int udc_read_control_request(struct nomadik_udc* dev_context, uint16_t wcount) {
+ const uint8_t* base_ptr = ( u8 *)udc_base_addr;
+ struct t_udc_end0_buffer* end0_buffer_ptr=(struct t_udc_end0_buffer*)dev_context->end0_buffer_ptr;
+ struct usb_ctrlrequest* control_req_ptr=(struct usb_ctrlrequest*)end0_buffer_ptr;
-+
++
+ DBG(3, "<==\n");
-+ DBG(4,"wcount=%u, end0_buffer_ptr->count=%u\n", wcount,
++ DBG(4,"wcount=%u, end0_buffer_ptr->count=%u\n", wcount,
+ end0_buffer_ptr->count);
-+
++
+ /* what did u call me for?? */
+ if (!wcount) {
+ return -EINVAL;
+ }
-+
++
+ /* buffer overrun, it should never happen */
+ if ( wcount>(MUSB_MAX_END0_PACKET-sizeof(struct usb_ctrlrequest)) ) {
-+ ERR("buffer overrun! wcount=%d\n", wcount );
-+ return -EINVAL;
-+ }
-+
++ ERR("buffer overrun! wcount=%d\n", wcount );
++ return -EINVAL;
++ }
++
+ /* need to have at least enough bytes for the control request
-+ * comment this out to enable fifo size < 8 bytes
++ * comment this out to enable fifo size < 8 bytes
+ */
+ if ( wcount<sizeof(struct usb_ctrlrequest) ) {
+ ERR("wcount=%d<sizeof(struct usb_ctrlrequest)=%d\n",
-+ wcount, (int)sizeof(struct usb_ctrlrequest));
-+ return -EINVAL;
++ wcount, (int)sizeof(struct usb_ctrlrequest));
++ return -EINVAL;
+ }
-+
-+#ifdef MUSB_PARANOID
-+ ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++
++#ifdef MUSB_PARANOID
++ ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
+#endif
-+
++
+ spin_lock(&dev_context->lock);
+ MUSB_SELECTEND(base_ptr, 0); /* select ep0 */
-+
++
+ /* count=0 means that I'm reading the USB standard header:
-+ * that's the first thing I need to read from the FIFO (8 bytes).
++ * that's the first thing I need to read from the FIFO (8 bytes).
+ */
+ if ( 0==end0_buffer_ptr->count ) {
+ DBG(4, "reading header\n" );
-+ udc_unload_fifo(base_ptr, 0, sizeof(struct usb_ctrlrequest),
++ udc_unload_fifo(base_ptr, 0, sizeof(struct usb_ctrlrequest),
+ (uint8_t*)control_req_ptr);
+ wcount-=sizeof(struct usb_ctrlrequest);
+ DBG(6, "header read\n");
-+
-+ /* data from the USB bus must be converted from LSB to
-+ * host-specific byte ordering; the control request header
-+ * tell me the payload length etc.
++
++ /* data from the USB bus must be converted from LSB to
++ * host-specific byte ordering; the control request header
++ * tell me the payload length etc.
+ */
+ le16_to_cpus( control_req_ptr->wLength );
+ le16_to_cpus( control_req_ptr->wIndex );
+ le16_to_cpus( control_req_ptr->wValue );
-+
-+ DBG(4, "bRequest=%02x, kind=%s, wValue=%04x, wIndex=%04x, wLength=%04x\n",
-+ control_req_ptr->bRequest, decode_request(control_req_ptr),
-+ control_req_ptr->wValue, control_req_ptr->wIndex,
++
++ DBG(4, "bRequest=%02x, kind=%s, wValue=%04x, wIndex=%04x, wLength=%04x\n",
++ control_req_ptr->bRequest, decode_request(control_req_ptr),
++ control_req_ptr->wValue, control_req_ptr->wIndex,
+ control_req_ptr->wLength);
-+
-+ if( control_req_ptr->bRequestType & USB_DIR_IN ) {
++
++ if( control_req_ptr->bRequestType & USB_DIR_IN ) {
+ /* write to host: up to wLength bytes */
+ end0_buffer_ptr->count=0;
+ dev_context->end0_stage = MUSB_END0_STAGE_TX;
-+ } else if( control_req_ptr->bRequestType & USB_DIR_OUT ) {
++ } else if( control_req_ptr->bRequestType & USB_DIR_OUT ) {
+ /* out to function: wLength to go for the payload */
+ end0_buffer_ptr->count=control_req_ptr->wLength;
+ dev_context->end0_stage = MUSB_END0_STAGE_RX;
-+ }
++ }
+ }
-+
-+ if ( wcount>0 ) {
++
++ if ( wcount>0 ) {
+ /* now Im reading the rest of it, this will never be executed I guess */
+ uint16_t offset=sizeof(struct usb_ctrlrequest)+ /* read past the header */
-+ (control_req_ptr->wLength)-(end0_buffer_ptr->count);
++ (control_req_ptr->wLength)-(end0_buffer_ptr->count);
+ udc_unload_fifo(base_ptr, 0, wcount, &end0_buffer_ptr->data[offset]);
+ end0_buffer_ptr->count-=wcount;
+ }
-+
-+ DBG(5, "end0_buffer_ptr->count=%d, ep0stage=%s, %s\n",
-+ end0_buffer_ptr->count, decode_ep0stage(dev_context->end0_stage),
-+ (end0_buffer_ptr->count)?"still to go":"header completed");
++
++ DBG(5, "end0_buffer_ptr->count=%d, ep0stage=%s, %s\n",
++ end0_buffer_ptr->count, decode_ep0stage(dev_context->end0_stage),
++ (end0_buffer_ptr->count)?"still to go":"header completed");
+ DBG(3, "==>\n");
-+
++
+ spin_unlock(&dev_context->lock);
-+
++
+ /* 0 header completed, <0 error, >0 bytes to go*/
+ return (end0_buffer_ptr->count);
+}
+/* ---------------------------------------------------------------------- */
+
+/**
-+ * 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;
+ 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();
+ 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 */
+ 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:
+ 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;
+}
+
+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) {
+/**
+ * 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.
+ */
+ 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(
+ 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)
+ 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;
+}
+ 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
+ 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
+ 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++;
+ 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)
+ const uint8_t* base_addr = (uint8_t*)udc_base_addr;
+ struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]);
+ uint16_t fifo_count = 0, wcount=end_ptr->maxpacket;
-+
-+
++
++
+ MUSB_SELECTEND(base_addr, bEnd);
+ csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd);
+ if ( csrval& MUSB_M_RXCSR_RXPKTRDY ) {
-+
++
+ /* this also handle residual (if any) */
-+ wcount = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd);
-+ if ( reqptr->actual < reqptr->length ) {
-+
-+ fifo_count = (uint16_t)min((int)wcount,
++ wcount = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd);
++ if ( reqptr->actual < reqptr->length ) {
++
++ fifo_count = (uint16_t)min((int)wcount,
+ (int)(reqptr->length - reqptr->actual));
-+ udc_unload_fifo(base_addr, bEnd, fifo_count,
++ udc_unload_fifo(base_addr, bEnd, fifo_count,
+ (uint8_t*)(reqptr->buf + reqptr->actual));
+ reqptr->actual += fifo_count;
-+
++
+ DBG(3, "fifo_count=%d, bEnd=0x%x, end_ptr->maxpacket=0x%x, wcount=0x%x, %s\n",\
+ fifo_count, bEnd, end_ptr->maxpacket, wcount, dump_usb_request(reqptr));
-+
++
+ /* ack the read! */
+ csrval &= ~MUSB_M_RXCSR_RXPKTRDY;
+ MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval);
-+ }
++ }
+ }
-+
++
+ /* reach the end or short packet detected */
-+ if ( reqptr->actual==reqptr->length || wcount<end_ptr->maxpacket ) {
++ if ( reqptr->actual==reqptr->length || wcount<end_ptr->maxpacket ) {
+ reqptr->status=0;
-+
-+ DBG(3, "completing reqptr=%p on bEnd=0x%x\n", reqptr, bEnd);
++
++ DBG(3, "completing reqptr=%p on bEnd=0x%x\n", reqptr, bEnd);
+ list_del( &reqptr->list );
-+ DBG(3, "queuing completion\n");
++ DBG(3, "queuing completion\n");
+ udc_complete_request(reqptr, reqptr->status); /* async complete */
+ }
-+
++
+ DBG(2, "==>");
+}
+
+/**
+ * Data ready for a request; called from IRQ
+ * @param dev_context the controller
-+ * @param req the request
++ * @param req the request
+ */
+void udc_ep_rx_irq(uint8_t bEnd)
+{
+ 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);
+ 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++;
+ 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" );
+}
+*
+*/
+
-+/**
++/**
+ * @pre dev_context!=NULL
+ */
+void udc_resume(void) {
+ }
+}
+
-+/**
++/**
+ * @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++)
+ nomadik_ep_disable(&dev_context->end[bEnd].ep);
+ }
+ (dev_context->end[0]).binactive = MUSB_GADGET_EP_ACTIVE;
-+
++
+ }
+ DBG(4, "==>\n");
+}
+ 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);
+ } 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" );
+}
+
+ 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;
+}
+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;
+}
+ */
+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.
+static char *decode_bits(uint16_t value) {
+ int i=0;
+ static char buf[64];
-+
++
+ for (; i<16;i++) {
-+ buf[15-i]=(value&(1<<i))?'1':'0';
++ buf[15-i]=(value&(1<<i))?'1':'0';
+ }
-+
++
+ return buf;
+}
+
+ */
+static char *decode_txcsr(uint16_t txcsr) {
+ static char buf[256];
-+ sprintf(buf, "%s (%s%s%s%s)",
++ sprintf(buf, "%s (%s%s%s%s)",
+ decode_bits(txcsr),
+ txcsr&MUSB_M_TXCSR_TXPKTRDY ? "[TXPKTRDY]":"",
+ txcsr&MUSB_M_TXCSR_AUTOSET ? "[MUSB_M_TXCSR_AUTOSET]":"",
+ txcsr&MUSB_M_TXCSR_DMAENAB ? "[MUSB_M_TXCSR_DMAENAB]":"",
-+ txcsr&MUSB_M_TXCSR_DMAMODE ? "[MUSB_M_TXCSR_DMAMODE]":"");
-+ return buf;
++ txcsr&MUSB_M_TXCSR_DMAMODE ? "[MUSB_M_TXCSR_DMAMODE]":"");
++ return buf;
+}
+
+/*
+static char *decode_ep0stage(uint8_t stage) {
+ static char buff[64];
+ uint8_t stallbit=stage&MUSB_END0_STAGE_STALL_BIT;
-+
++
+ stage=stage&~stage&MUSB_END0_STAGE_STALL_BIT;
+ sprintf(buff, "%s%s", (stallbit)? "stall-" : "",
+ (stage==MUSB_END0_STAGE_SETUP)
+ (stage==MUSB_END0_STAGE_RX)
+ ? "rx" :
+ (stage==MUSB_END0_STAGE_STATUSIN)
-+ ? "statusin" :
++ ? "statusin" :
+ (stage==MUSB_END0_STAGE_STATUSOUT)
+ ? "statusout" : "error");
+ return buff;
+ * Dump core registers whose reads are non-destructive.
+ * @param base_addr
+ * @param multipoint
-+ * @param bEnd
++ * @param bEnd
+ */
+void udc_dump_regs(uint8_t* base_addr, int multipoint, uint8_t bEnd)
+{
-+
-+
-+ MUSB_SELECTEND(base_addr, bEnd);
-+
++
++
++ MUSB_SELECTEND(base_addr, bEnd);
++
+ if(!bEnd) {
+ printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n",
+ MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0, 0),
+ MUSB_READCSR8(base_addr, MUSB_O_HDRC_TXINTERVAL, bEnd),
+ MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd));
+ }
-+
++
+ if( multipoint) {
+ printk(KERN_INFO " TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n",
+ MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_TXFUNCADDR)),
+
+
+/**
-+ * Enable the Controller
++ * Enable the Controller
+ */
+void musb_enable(void)
+{
+ uint8_t* udc_base = (uint8_t*)udc_base_addr;
-+
++
+ DBG(4, "<==\n");
-+
++
+ /* Set INT enable registers, enable interrupts */
+ MUSB_WRITE16(udc_base, MUSB_O_HDRC_INTRTXE, dev_context->end_mask);
+ MUSB_WRITE16(udc_base, MUSB_O_HDRC_INTRRXE, dev_context->end_mask & 0xfffe);
+ /* don't enable suspend mode! */
-+ MUSB_WRITE8(udc_base, MUSB_O_HDRC_INTRUSBE, 0xf7);
-+
-+
++ MUSB_WRITE8(udc_base, MUSB_O_HDRC_INTRUSBE, 0xf7);
++
++
+ DBG(3, "%s INTRUSBE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRUSBE));
+ DBG(3, "%s INTRTXE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRTXE));
+ DBG(3, "%s INTRRXE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRRXE));
+
+
+/**
-+ * 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)
+ {
+ 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",
+ 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
+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;
+}
+
+ DECLARE_COMPLETION(done);
+ if (!dev_context)
+ return -ENODEV;
-+
++
+ dev_context->done = &done;
+ nomadik_release_udc();
+ return 0;
+
+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
+ *
+ * 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)
+
+
+/*
-+ * MUSBMHDRC Register map
++ * MUSBMHDRC Register map
+ */
+
+/* Common USB registers */
+
+#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 */
+
+
+/* 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
+#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
+#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
+ u8 ackwait;
+ u8 dma_channel;
+ u8 is_tx;
-+ u8 end_number;
++ u8 end_number;
+ u16 dma_counter;
+ int lch;
+ struct nomadik_udc *udc;
+ u8 end_number;
+ unsigned dma_bytes;
+ unsigned mapped:1;
-+};
++};
+
+struct nomadik_udc{
+ spinlock_t lock;
+ 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
+ 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)
+#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
+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
+
+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
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**************************************************
-+ OTG - HNP and SRP
++ OTG - HNP and SRP
+**************************************************/
+
+#include <linux/delay.h>
+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;
+
+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));
+
+ 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);
+
+ 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 ");
+
+}
+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);
+
+ 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);
+
+
+
+
-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
+ *
+ * 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
+ */
+
+/***********************************
+{
+ 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
+ *
+ * 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__
+}
+
+#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
+ *
+ * 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
+
+#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 */
+#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
+/* 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))))
+/* 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))))
+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
*/
#include <linux/module.h>
#include <linux/kernel.h>
-@@ -24,18 +28,28 @@
+ #include <linux/errno.h>
+ #include <linux/string.h>
+@@ -22,22 +26,32 @@
+ #include <linux/ioport.h>
+ #include <linux/list.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/clk.h>
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));
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.
*/
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) {
}
}
-@@ -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;
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;
}
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;
/*
* 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;
}
* 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
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;
}
{
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;
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;
}
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) {
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);
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[] = {
{
},
{ 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,
};
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;
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
+#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,
+ 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
+#define DEBUG_LEVEL4 DBGL_HCL_DEV
+
+
-+typedef enum
++typedef enum
+{
+ DBGL_OFF = 0,
+ DBGL_PUBLIC_FUNC_IN = MASK_BIT0,
+} t_dbg_level;
+
+
-+
-+#ifdef __DEBUG
-+
++
++#ifdef __DEBUG
++
+/*--------------------------------------------------------------------------*
+ * Macro *
+ *--------------------------------------------------------------------------*/
-+
++
+/* Begin of Private definitions */
+
+/*
+#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) \
+#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):\
+#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
+ ((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 */
+
+/* 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
+ * 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;
+
+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;
+
+/*
+ * 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 ,
+ HCL_FREQ_22MHZ,
+ HCL_FREQ_24MHZ,
+ HCL_FREQ_48MHZ
-+} t_frequency;
++} t_frequency;
+
+
+
+
+
+/*-----------------------------------------------------------------------------
-+ * Keyword definition
++ * Keyword definition
+ *---------------------------------------------------------------------------*/
+#define PUBLIC /* Extern by default */
+#define PRIVATE static
+#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
+#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1)
+#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2)
+#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3)
-+
++
+/*-----------------------------------------------------------------------------
+ * Halfword shift definition
+ *---------------------------------------------------------------------------*/
+ *---------------------------------------------------------------------------*/
+ #define ONE_KB (1024)
+ #define ONE_MB (ONE_KB * ONE_KB)
-+
-+
++
++
+/*-----------------------------------------------------------------------------
+ * Address translation macros declaration
+ *---------------------------------------------------------------------------*/
+#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
+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
+ 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
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
-+ * Description : Public Header file of Smart Graphic Accelarator (SGA) module
++ * Description : Public Header file of Smart Graphic Accelarator (SGA) module
+ *
+ *****************************************************************************/
+#ifndef _SGA_H_
+} /* 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
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
-+ * Description : This module provides interrupt routines for the
++ * Description : This module provides interrupt routines for the
+ * NOMADIK SGA Controller
+ *****************************************************************************/
+/*--------------------------------------------------------------------------*
+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)
+{
+* 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.
+* 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)
+{
+* 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.
+* 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)
+{
+ }
+ }
+}
-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
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
-+ * Description : Public Header file of Smart Graphics Accelerator
++ * Description : Public Header file of Smart Graphics Accelerator
+ * module containing interrupts APIs
+ *****************************************************************************/
+
+#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
+#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
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
-+ * Description : Private Header file of SGA Controller module
++ * Description : Private Header file of SGA Controller module
+ *
+ *****************************************************************************/
+
+
+#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 )
+
+
+/*-----------------------------------------------------------------------------
+ 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 */
+ 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;
+
+
+ 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 */
+ /*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 */
+#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 */
+#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 */
+#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 */
+
+/* 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
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
-+ * Description : Private Header file of Smart Graphics Accelerator
++ * Description : Private Header file of Smart Graphics Accelerator
+ * module containing interrupts APIs
+ *****************************************************************************/
+#ifndef _SGA_P_H_
+#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
+#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
+#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
+/******************************************************************************/
+
+#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
+}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
+
+#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
+}
+
+// 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
+ * 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
+
+#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
+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
+
+
+#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
+typedef long INT4;
+
+#endif /* _SGA_TYPS_H */
-diff -Nauprw linux-2.6.20/fs/Kconfig ../new/linux-2.6.20/fs/Kconfig
---- linux-2.6.20/fs/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/fs/Kconfig 2008-09-17 13:23:34.000000000 +0530
-@@ -1196,6 +1196,10 @@ config EFS_FS
+--- linux-2.6.20.orig/fs/Kconfig
++++ linux-2.6.20/fs/Kconfig
+@@ -1194,10 +1194,14 @@ config EFS_FS
+ about EFS see its home page at <http://aeschi.ch.eu.org/efs/>.
+
To compile the EFS file system support as a module, choose M here: the
module will be called efs.
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 *);
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);
}
+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);
+}
+
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
- {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}, {
};
for (p = simple_ones; p->name; p++)
create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
-diff -Nauprw linux-2.6.20/fs/yaffs2/devextras.h ../new/linux-2.6.20/fs/yaffs2/devextras.h
---- linux-2.6.20/fs/yaffs2/devextras.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/devextras.h 2008-09-12 12:54:02.000000000 +0530
+
+ proc_symlink("mounts", NULL, "self/mounts");
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/Kconfig
+@@ -0,0 +1,156 @@
++#
++# YAFFS file system configurations
++#
++
++config YAFFS_FS
++ tristate "YAFFS2 file system support"
++ default n
++ depends on MTD
++ select YAFFS_YAFFS1
++ select YAFFS_YAFFS2
++ help
++ YAFFS2, or Yet Another Flash Filing System, is a filing system
++ optimised for NAND Flash chips.
++
++ To compile the YAFFS2 file system support as a module, choose M
++ here: the module will be called yaffs2.
++
++ If unsure, say N.
++
++ Further information on YAFFS2 is available at
++ <http://www.aleph1.co.uk/yaffs/>.
++
++config YAFFS_YAFFS1
++ bool "512 byte / page devices"
++ depends on YAFFS_FS
++ default y
++ help
++ Enable YAFFS1 support -- yaffs for 512 byte / page devices
++
++ Not needed for 2K-page devices.
++
++ If unsure, say Y.
++
++config YAFFS_9BYTE_TAGS
++ bool "Use older-style on-NAND data format with pageStatus byte"
++ depends on YAFFS_YAFFS1
++ default n
++ help
++
++ Older-style on-NAND data format has a "pageStatus" byte to record
++ chunk/page state. This byte is zero when the page is discarded.
++ Choose this option if you have existing on-NAND data using this
++ format that you need to continue to support. New data written
++ also uses the older-style format. Note: Use of this option
++ generally requires that MTD's oob layout be adjusted to use the
++ older-style format. See notes on tags formats and MTD versions
++ in yaffs_mtdif1.c.
++
++ If unsure, say N.
++
++config YAFFS_DOES_ECC
++ bool "Lets Yaffs do its own ECC"
++ depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
++ default n
++ help
++ This enables Yaffs to use its own ECC functions instead of using
++ the ones from the generic MTD-NAND driver.
++
++ If unsure, say N.
++
++config YAFFS_ECC_WRONG_ORDER
++ bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
++ depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
++ default n
++ help
++ This makes yaffs_ecc.c use the same ecc byte order as Steven
++ Hill's nand_ecc.c. If not set, then you get the same ecc byte
++ order as SmartMedia.
++
++ If unsure, say N.
++
++config YAFFS_YAFFS2
++ bool "2048 byte (or larger) / page devices"
++ depends on YAFFS_FS
++ default y
++ help
++ Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
++
++ If unsure, say Y.
++
++config YAFFS_AUTO_YAFFS2
++ bool "Autoselect yaffs2 format"
++ depends on YAFFS_YAFFS2
++ default y
++ help
++ Without this, you need to explicitely use yaffs2 as the file
++ system type. With this, you can say "yaffs" and yaffs or yaffs2
++ will be used depending on the device page size (yaffs on
++ 512-byte page devices, yaffs2 on 2K page devices).
++
++ If unsure, say Y.
++
++config YAFFS_DISABLE_LAZY_LOAD
++ bool "Disable lazy loading"
++ depends on YAFFS_YAFFS2
++ default n
++ help
++ "Lazy loading" defers loading file details until they are
++ required. This saves mount time, but makes the first look-up
++ a bit longer.
++
++ Lazy loading will only happen if enabled by this option being 'n'
++ and if the appropriate tags are available, else yaffs2 will
++ automatically fall back to immediate loading and do the right
++ thing.
++
++ Lazy laoding will be required by checkpointing.
++
++ Setting this to 'y' will disable lazy loading.
++
++ If unsure, say N.
++
++
++config YAFFS_DISABLE_WIDE_TNODES
++ bool "Turn off wide tnodes"
++ depends on YAFFS_FS
++ default n
++ help
++ Wide tnodes are only used for NAND arrays >=32MB for 512-byte
++ page devices and >=128MB for 2k page devices. They use slightly
++ more RAM but are faster since they eliminate chunk group
++ searching.
++
++ Setting this to 'y' will force tnode width to 16 bits and save
++ memory but make large arrays slower.
++
++ If unsure, say N.
++
++config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
++ bool "Force chunk erase check"
++ depends on YAFFS_FS
++ default n
++ help
++ Normally YAFFS only checks chunks before writing until an erased
++ chunk is found. This helps to detect any partially written
++ chunks that might have happened due to power loss.
++
++ Enabling this forces on the test that chunks are erased in flash
++ before writing to them. This takes more time but is potentially
++ a bit more secure.
++
++ Suggest setting Y during development and ironing out driver
++ issues etc. Suggest setting to N if you want faster writing.
++
++ If unsure, say Y.
++
++config YAFFS_SHORT_NAMES_IN_RAM
++ bool "Cache short names in RAM"
++ depends on YAFFS_FS
++ default y
++ help
++ If this config is set, then short names are stored with the
++ yaffs_Object. This costs an extra 16 bytes of RAM per object,
++ but makes look-ups faster.
++
++ If unsure, say Y.
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for the linux YAFFS filesystem routines.
++#
++
++obj-$(CONFIG_YAFFS_FS) += yaffs.o
++
++yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
++yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
++yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
++yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/devextras.h
@@ -0,0 +1,264 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+#endif
+
+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/Kconfig ../new/linux-2.6.20/fs/yaffs2/Kconfig
---- linux-2.6.20/fs/yaffs2/Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/Kconfig 2008-09-12 12:54:02.000000000 +0530
-@@ -0,0 +1,156 @@
-+#
-+# YAFFS file system configurations
-+#
-+
-+config YAFFS_FS
-+ tristate "YAFFS2 file system support"
-+ default n
-+ depends on MTD
-+ select YAFFS_YAFFS1
-+ select YAFFS_YAFFS2
-+ help
-+ YAFFS2, or Yet Another Flash Filing System, is a filing system
-+ optimised for NAND Flash chips.
-+
-+ To compile the YAFFS2 file system support as a module, choose M
-+ here: the module will be called yaffs2.
-+
-+ If unsure, say N.
-+
-+ Further information on YAFFS2 is available at
-+ <http://www.aleph1.co.uk/yaffs/>.
-+
-+config YAFFS_YAFFS1
-+ bool "512 byte / page devices"
-+ depends on YAFFS_FS
-+ default y
-+ help
-+ Enable YAFFS1 support -- yaffs for 512 byte / page devices
-+
-+ Not needed for 2K-page devices.
-+
-+ If unsure, say Y.
-+
-+config YAFFS_9BYTE_TAGS
-+ bool "Use older-style on-NAND data format with pageStatus byte"
-+ depends on YAFFS_YAFFS1
-+ default n
-+ help
-+
-+ Older-style on-NAND data format has a "pageStatus" byte to record
-+ chunk/page state. This byte is zero when the page is discarded.
-+ Choose this option if you have existing on-NAND data using this
-+ format that you need to continue to support. New data written
-+ also uses the older-style format. Note: Use of this option
-+ generally requires that MTD's oob layout be adjusted to use the
-+ older-style format. See notes on tags formats and MTD versions
-+ in yaffs_mtdif1.c.
-+
-+ If unsure, say N.
-+
-+config YAFFS_DOES_ECC
-+ bool "Lets Yaffs do its own ECC"
-+ depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
-+ default n
-+ help
-+ This enables Yaffs to use its own ECC functions instead of using
-+ the ones from the generic MTD-NAND driver.
-+
-+ If unsure, say N.
-+
-+config YAFFS_ECC_WRONG_ORDER
-+ bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
-+ depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
-+ default n
-+ help
-+ This makes yaffs_ecc.c use the same ecc byte order as Steven
-+ Hill's nand_ecc.c. If not set, then you get the same ecc byte
-+ order as SmartMedia.
-+
-+ If unsure, say N.
-+
-+config YAFFS_YAFFS2
-+ bool "2048 byte (or larger) / page devices"
-+ depends on YAFFS_FS
-+ default y
-+ help
-+ Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
-+
-+ If unsure, say Y.
-+
-+config YAFFS_AUTO_YAFFS2
-+ bool "Autoselect yaffs2 format"
-+ depends on YAFFS_YAFFS2
-+ default y
-+ help
-+ Without this, you need to explicitely use yaffs2 as the file
-+ system type. With this, you can say "yaffs" and yaffs or yaffs2
-+ will be used depending on the device page size (yaffs on
-+ 512-byte page devices, yaffs2 on 2K page devices).
-+
-+ If unsure, say Y.
-+
-+config YAFFS_DISABLE_LAZY_LOAD
-+ bool "Disable lazy loading"
-+ depends on YAFFS_YAFFS2
-+ default n
-+ help
-+ "Lazy loading" defers loading file details until they are
-+ required. This saves mount time, but makes the first look-up
-+ a bit longer.
-+
-+ Lazy loading will only happen if enabled by this option being 'n'
-+ and if the appropriate tags are available, else yaffs2 will
-+ automatically fall back to immediate loading and do the right
-+ thing.
-+
-+ Lazy laoding will be required by checkpointing.
-+
-+ Setting this to 'y' will disable lazy loading.
-+
-+ If unsure, say N.
-+
-+
-+config YAFFS_DISABLE_WIDE_TNODES
-+ bool "Turn off wide tnodes"
-+ depends on YAFFS_FS
-+ default n
-+ help
-+ Wide tnodes are only used for NAND arrays >=32MB for 512-byte
-+ page devices and >=128MB for 2k page devices. They use slightly
-+ more RAM but are faster since they eliminate chunk group
-+ searching.
-+
-+ Setting this to 'y' will force tnode width to 16 bits and save
-+ memory but make large arrays slower.
-+
-+ If unsure, say N.
-+
-+config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
-+ bool "Force chunk erase check"
-+ depends on YAFFS_FS
-+ default n
-+ help
-+ Normally YAFFS only checks chunks before writing until an erased
-+ chunk is found. This helps to detect any partially written
-+ chunks that might have happened due to power loss.
-+
-+ Enabling this forces on the test that chunks are erased in flash
-+ before writing to them. This takes more time but is potentially
-+ a bit more secure.
-+
-+ Suggest setting Y during development and ironing out driver
-+ issues etc. Suggest setting to N if you want faster writing.
-+
-+ If unsure, say Y.
-+
-+config YAFFS_SHORT_NAMES_IN_RAM
-+ bool "Cache short names in RAM"
-+ depends on YAFFS_FS
-+ default y
-+ help
-+ If this config is set, then short names are stored with the
-+ yaffs_Object. This costs an extra 16 bytes of RAM per object,
-+ but makes look-ups faster.
-+
-+ If unsure, say Y.
-diff -Nauprw linux-2.6.20/fs/yaffs2/Makefile ../new/linux-2.6.20/fs/yaffs2/Makefile
---- linux-2.6.20/fs/yaffs2/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/Makefile 2008-09-12 12:54:02.000000000 +0530
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the linux YAFFS filesystem routines.
-+#
-+
-+obj-$(CONFIG_YAFFS_FS) += yaffs.o
-+
-+yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
-+yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
-+yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
-+yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
-diff -Nauprw linux-2.6.20/fs/yaffs2/moduleconfig.h ../new/linux-2.6.20/fs/yaffs2/moduleconfig.h
---- linux-2.6.20/fs/yaffs2/moduleconfig.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/moduleconfig.h 2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/moduleconfig.h
@@ -0,0 +1,65 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+#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.
+
+
+
-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.
+
+#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.
+
+}
+
-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.
+ 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.
+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.
+
+ 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.
+void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
+
+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffsinterface.h ../new/linux-2.6.20/fs/yaffs2/yaffsinterface.h
---- linux-2.6.20/fs/yaffs2/yaffsinterface.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffsinterface.h 2008-09-12 12:54:05.000000000 +0530
-@@ -0,0 +1,21 @@
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif.c
+@@ -0,0 +1,241 @@
++/*
++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
++ *
++ * Copyright (C) 2002-2007 Aleph One Ltd.
++ * for Toby Churchill Ltd and Brightstar Engineering
++ *
++ * Created by Charles Manning <charles@aleph1.co.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++const char *yaffs_mtdif_c_version =
++ "$Id: yaffs_mtdif.c,v 1.21 2007/12/13 15:35:18 wookey Exp $";
++
++#include "yportenv.h"
++
++
++#include "yaffs_mtdif.h"
++
++#include "linux/mtd/mtd.h"
++#include "linux/types.h"
++#include "linux/time.h"
++#include "linux/mtd/nand.h"
++
++#if (MTD_VERSION_CODE < MTD_VERSION(2,6,18))
++static struct nand_oobinfo yaffs_oobinfo = {
++ .useecc = 1,
++ .eccbytes = 6,
++ .eccpos = {8, 9, 10, 13, 14, 15}
++};
++
++static struct nand_oobinfo yaffs_noeccinfo = {
++ .useecc = 0,
++};
++#endif
++
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
++{
++ oob[0] = spare->tagByte0;
++ oob[1] = spare->tagByte1;
++ oob[2] = spare->tagByte2;
++ oob[3] = spare->tagByte3;
++ oob[4] = spare->tagByte4;
++ oob[5] = spare->tagByte5 & 0x3f;
++ oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
++ oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
++ oob[6] = spare->tagByte6;
++ oob[7] = spare->tagByte7;
++}
++
++static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
++{
++ struct yaffs_NANDSpare *nspare = (struct yaffs_NANDSpare *)spare;
++ spare->tagByte0 = oob[0];
++ spare->tagByte1 = oob[1];
++ spare->tagByte2 = oob[2];
++ spare->tagByte3 = oob[3];
++ spare->tagByte4 = oob[4];
++ spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
++ spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y';
++ spare->pageStatus = oob[5] & 0x40 ? 0xff : 0;
++ spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
++ spare->tagByte6 = oob[6];
++ spare->tagByte7 = oob[7];
++ spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;
++
++ nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
++}
++#endif
++
++int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
++ const __u8 * data, const yaffs_Spare * spare)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++ struct mtd_oob_ops ops;
++#endif
++ size_t dummy;
++ int retval = 0;
++
++ loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++ __u8 spareAsBytes[8]; /* OOB */
++
++ if (data && !spare)
++ retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
++ &dummy, data);
++ else if (spare) {
++ if (dev->useNANDECC) {
++ translate_spare2oob(spare, spareAsBytes);
++ ops.mode = MTD_OOB_AUTO;
++ ops.ooblen = 8; /* temp hack */
++ } else {
++ ops.mode = MTD_OOB_RAW;
++ ops.ooblen = YAFFS_BYTES_PER_SPARE;
++ }
++ ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
++ ops.datbuf = (u8 *)data;
++ ops.ooboffs = 0;
++ ops.oobbuf = spareAsBytes;
++ retval = mtd->write_oob(mtd, addr, &ops);
++ }
++#else
++ __u8 *spareAsBytes = (__u8 *) spare;
++
++ if (data && spare) {
++ if (dev->useNANDECC)
++ retval =
++ mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
++ &dummy, data, spareAsBytes,
++ &yaffs_oobinfo);
++ else
++ retval =
++ mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
++ &dummy, data, spareAsBytes,
++ &yaffs_noeccinfo);
++ } else {
++ if (data)
++ retval =
++ mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
++ data);
++ if (spare)
++ retval =
++ mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
++ &dummy, spareAsBytes);
++ }
++#endif
++
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
++int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
++ yaffs_Spare * spare)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++ struct mtd_oob_ops ops;
++#endif
++ size_t dummy;
++ int retval = 0;
++
++ loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++ __u8 spareAsBytes[8]; /* OOB */
++
++ if (data && !spare)
++ retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
++ &dummy, data);
++ else if (spare) {
++ if (dev->useNANDECC) {
++ ops.mode = MTD_OOB_AUTO;
++ ops.ooblen = 8; /* temp hack */
++ } else {
++ ops.mode = MTD_OOB_RAW;
++ ops.ooblen = YAFFS_BYTES_PER_SPARE;
++ }
++ ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
++ ops.datbuf = data;
++ ops.ooboffs = 0;
++ ops.oobbuf = spareAsBytes;
++ retval = mtd->read_oob(mtd, addr, &ops);
++ if (dev->useNANDECC)
++ translate_oob2spare(spare, spareAsBytes);
++ }
++#else
++ __u8 *spareAsBytes = (__u8 *) spare;
++
++ if (data && spare) {
++ if (dev->useNANDECC) {
++ /* Careful, this call adds 2 ints */
++ /* to the end of the spare data. Calling function */
++ /* should allocate enough memory for spare, */
++ /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
++ retval =
++ mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
++ &dummy, data, spareAsBytes,
++ &yaffs_oobinfo);
++ } else {
++ retval =
++ mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
++ &dummy, data, spareAsBytes,
++ &yaffs_noeccinfo);
++ }
++ } else {
++ if (data)
++ retval =
++ mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
++ data);
++ if (spare)
++ retval =
++ mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
++ &dummy, spareAsBytes);
++ }
++#endif
++
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
++int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++ __u32 addr =
++ ((loff_t) blockNumber) * dev->nDataBytesPerChunk
++ * dev->nChunksPerBlock;
++ struct erase_info ei;
++ int retval = 0;
++
++ ei.mtd = mtd;
++ ei.addr = addr;
++ ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
++ ei.time = 1000;
++ ei.retries = 2;
++ ei.callback = NULL;
++ ei.priv = (u_long) dev;
++
++ /* Todo finish off the ei if required */
++
++ sema_init(&dev->sem, 0);
++
++ retval = mtd->erase(mtd, &ei);
++
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
++int nandmtd_InitialiseNAND(yaffs_Device * dev)
++{
++ return YAFFS_OK;
++}
++
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif.h
+@@ -0,0 +1,27 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * 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.
+}
+
+#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.
+ 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.
+ 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.
+ yaffs_BlockState * state, int *sequenceNumber);
+
+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.c
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.c 2008-09-12 12:54:03.000000000 +0530
-@@ -0,0 +1,241 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+const char *yaffs_mtdif_c_version =
-+ "$Id: yaffs_mtdif.c,v 1.21 2007/12/13 15:35:18 wookey Exp $";
-+
-+#include "yportenv.h"
-+
-+
-+#include "yaffs_mtdif.h"
-+
-+#include "linux/mtd/mtd.h"
-+#include "linux/types.h"
-+#include "linux/time.h"
-+#include "linux/mtd/nand.h"
-+
-+#if (MTD_VERSION_CODE < MTD_VERSION(2,6,18))
-+static struct nand_oobinfo yaffs_oobinfo = {
-+ .useecc = 1,
-+ .eccbytes = 6,
-+ .eccpos = {8, 9, 10, 13, 14, 15}
-+};
-+
-+static struct nand_oobinfo yaffs_noeccinfo = {
-+ .useecc = 0,
-+};
-+#endif
-+
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
-+{
-+ oob[0] = spare->tagByte0;
-+ oob[1] = spare->tagByte1;
-+ oob[2] = spare->tagByte2;
-+ oob[3] = spare->tagByte3;
-+ oob[4] = spare->tagByte4;
-+ oob[5] = spare->tagByte5 & 0x3f;
-+ oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
-+ oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
-+ oob[6] = spare->tagByte6;
-+ oob[7] = spare->tagByte7;
-+}
-+
-+static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
-+{
-+ struct yaffs_NANDSpare *nspare = (struct yaffs_NANDSpare *)spare;
-+ spare->tagByte0 = oob[0];
-+ spare->tagByte1 = oob[1];
-+ spare->tagByte2 = oob[2];
-+ spare->tagByte3 = oob[3];
-+ spare->tagByte4 = oob[4];
-+ spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
-+ spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y';
-+ spare->pageStatus = oob[5] & 0x40 ? 0xff : 0;
-+ spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
-+ spare->tagByte6 = oob[6];
-+ spare->tagByte7 = oob[7];
-+ spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;
-+
-+ nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
-+}
-+#endif
-+
-+int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
-+ const __u8 * data, const yaffs_Spare * spare)
-+{
-+ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+ struct mtd_oob_ops ops;
-+#endif
-+ size_t dummy;
-+ int retval = 0;
-+
-+ loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+ __u8 spareAsBytes[8]; /* OOB */
-+
-+ if (data && !spare)
-+ retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
-+ &dummy, data);
-+ else if (spare) {
-+ if (dev->useNANDECC) {
-+ translate_spare2oob(spare, spareAsBytes);
-+ ops.mode = MTD_OOB_AUTO;
-+ ops.ooblen = 8; /* temp hack */
-+ } else {
-+ ops.mode = MTD_OOB_RAW;
-+ ops.ooblen = YAFFS_BYTES_PER_SPARE;
-+ }
-+ ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
-+ ops.datbuf = (u8 *)data;
-+ ops.ooboffs = 0;
-+ ops.oobbuf = spareAsBytes;
-+ retval = mtd->write_oob(mtd, addr, &ops);
-+ }
-+#else
-+ __u8 *spareAsBytes = (__u8 *) spare;
-+
-+ if (data && spare) {
-+ if (dev->useNANDECC)
-+ retval =
-+ mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+ &dummy, data, spareAsBytes,
-+ &yaffs_oobinfo);
-+ else
-+ retval =
-+ mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+ &dummy, data, spareAsBytes,
-+ &yaffs_noeccinfo);
-+ } else {
-+ if (data)
-+ retval =
-+ mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
-+ data);
-+ if (spare)
-+ retval =
-+ mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
-+ &dummy, spareAsBytes);
-+ }
-+#endif
-+
-+ if (retval == 0)
-+ return YAFFS_OK;
-+ else
-+ return YAFFS_FAIL;
-+}
-+
-+int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
-+ yaffs_Spare * spare)
-+{
-+ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+ struct mtd_oob_ops ops;
-+#endif
-+ size_t dummy;
-+ int retval = 0;
-+
-+ loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+ __u8 spareAsBytes[8]; /* OOB */
-+
-+ if (data && !spare)
-+ retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
-+ &dummy, data);
-+ else if (spare) {
-+ if (dev->useNANDECC) {
-+ ops.mode = MTD_OOB_AUTO;
-+ ops.ooblen = 8; /* temp hack */
-+ } else {
-+ ops.mode = MTD_OOB_RAW;
-+ ops.ooblen = YAFFS_BYTES_PER_SPARE;
-+ }
-+ ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
-+ ops.datbuf = data;
-+ ops.ooboffs = 0;
-+ ops.oobbuf = spareAsBytes;
-+ retval = mtd->read_oob(mtd, addr, &ops);
-+ if (dev->useNANDECC)
-+ translate_oob2spare(spare, spareAsBytes);
-+ }
-+#else
-+ __u8 *spareAsBytes = (__u8 *) spare;
-+
-+ if (data && spare) {
-+ if (dev->useNANDECC) {
-+ /* Careful, this call adds 2 ints */
-+ /* to the end of the spare data. Calling function */
-+ /* should allocate enough memory for spare, */
-+ /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
-+ retval =
-+ mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+ &dummy, data, spareAsBytes,
-+ &yaffs_oobinfo);
-+ } else {
-+ retval =
-+ mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+ &dummy, data, spareAsBytes,
-+ &yaffs_noeccinfo);
-+ }
-+ } else {
-+ if (data)
-+ retval =
-+ mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
-+ data);
-+ if (spare)
-+ retval =
-+ mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
-+ &dummy, spareAsBytes);
-+ }
-+#endif
-+
-+ if (retval == 0)
-+ return YAFFS_OK;
-+ else
-+ return YAFFS_FAIL;
-+}
-+
-+int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
-+{
-+ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+ __u32 addr =
-+ ((loff_t) blockNumber) * dev->nDataBytesPerChunk
-+ * dev->nChunksPerBlock;
-+ struct erase_info ei;
-+ int retval = 0;
-+
-+ ei.mtd = mtd;
-+ ei.addr = addr;
-+ ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
-+ ei.time = 1000;
-+ ei.retries = 2;
-+ ei.callback = NULL;
-+ ei.priv = (u_long) dev;
-+
-+ /* Todo finish off the ei if required */
-+
-+ sema_init(&dev->sem, 0);
-+
-+ retval = mtd->erase(mtd, &ei);
-+
-+ if (retval == 0)
-+ return YAFFS_OK;
-+ else
-+ return YAFFS_FAIL;
-+}
-+
-+int nandmtd_InitialiseNAND(yaffs_Device * dev)
-+{
-+ return YAFFS_OK;
-+}
-+
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.h
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.h 2008-09-12 12:54:03.000000000 +0530
-@@ -0,0 +1,27 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+#ifndef __YAFFS_MTDIF_H__
-+#define __YAFFS_MTDIF_H__
-+
-+#include "yaffs_guts.h"
-+
-+int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
-+ const __u8 * data, const yaffs_Spare * spare);
-+int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
-+ yaffs_Spare * spare);
-+int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber);
-+int nandmtd_InitialiseNAND(yaffs_Device * dev);
-+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.c ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.c
---- linux-2.6.20/fs/yaffs2/yaffs_nand.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.c 2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_nand.c
@@ -0,0 +1,134 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+
+
+
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h ../new/linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h
---- linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h 2008-09-12 12:54:04.000000000 +0530
-@@ -0,0 +1,39 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+/* Interface to emulated NAND functions (2k page size) */
-+
-+#ifndef __YAFFS_NANDEMUL2K_H__
-+#define __YAFFS_NANDEMUL2K_H__
-+
-+#include "yaffs_guts.h"
-+
-+int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
-+ int chunkInNAND, const __u8 * data,
-+ yaffs_ExtendedTags * tags);
-+int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
-+ int chunkInNAND, __u8 * data,
-+ yaffs_ExtendedTags * tags);
-+int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
-+int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
-+ yaffs_BlockState * state, int *sequenceNumber);
-+int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
-+ int blockInNAND);
-+int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
-+int nandemul2k_GetBytesPerChunk(void);
-+int nandemul2k_GetChunksPerBlock(void);
-+int nandemul2k_GetNumberOfBlocks(void);
-+
-+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.h ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.h
---- linux-2.6.20/fs/yaffs2/yaffs_nand.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.h 2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_nand.h
@@ -0,0 +1,44 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+
+#endif
+
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c
---- linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c 2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h
+@@ -0,0 +1,39 @@
++/*
++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
++ *
++ * Copyright (C) 2002-2007 Aleph One Ltd.
++ * for Toby Churchill Ltd and Brightstar Engineering
++ *
++ * Created by Charles Manning <charles@aleph1.co.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 2.1 as
++ * published by the Free Software Foundation.
++ *
++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
++ */
++
++/* Interface to emulated NAND functions (2k page size) */
++
++#ifndef __YAFFS_NANDEMUL2K_H__
++#define __YAFFS_NANDEMUL2K_H__
++
++#include "yaffs_guts.h"
++
++int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
++ int chunkInNAND, const __u8 * data,
++ yaffs_ExtendedTags * tags);
++int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
++ int chunkInNAND, __u8 * data,
++ yaffs_ExtendedTags * tags);
++int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
++int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
++ yaffs_BlockState * state, int *sequenceNumber);
++int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
++ int blockInNAND);
++int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
++int nandemul2k_GetBytesPerChunk(void);
++int nandemul2k_GetChunksPerBlock(void);
++int nandemul2k_GetNumberOfBlocks(void);
++
++#endif
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c
@@ -0,0 +1,52 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+
+ }
+}
-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.
+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.
+ 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.
+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
+ }
+/* 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.
+ 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.
+
+ 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.
+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.
+ 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.
+void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
+int yaffs_ValidateTags(yaffs_ExtendedTags * tags);
+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yportenv.h ../new/linux-2.6.20/fs/yaffs2/yportenv.h
---- linux-2.6.20/fs/yaffs2/yportenv.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yportenv.h 2008-09-12 12:54:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffsinterface.h
+@@ -0,0 +1,21 @@
++/*
++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
++ *
++ * Copyright (C) 2002-2007 Aleph One Ltd.
++ * for Toby Churchill Ltd and Brightstar Engineering
++ *
++ * Created by Charles Manning <charles@aleph1.co.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 2.1 as
++ * published by the Free Software Foundation.
++ *
++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
++ */
++
++#ifndef __YAFFSINTERFACE_H__
++#define __YAFFSINTERFACE_H__
++
++int yaffs_Initialise(unsigned nBlocks);
++
++#endif
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yportenv.h
@@ -0,0 +1,200 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+#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
+ *
+#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
+#endif
+
+/* END */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/debug.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug.h 2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S
+@@ -0,0 +1,38 @@
++/* linux/include/asm-arm/arch-integrator/debug-macro.S
++ *
++ * Debugging macro include header
++ *
++ * Copyright (C) 1994-1999 Russell King
++ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++*/
++
++#include <linux/amba/serial.h>
++
++ .macro addruart,rx
++ mrc p15, 0, \rx, c1, c0
++ tst \rx, #1 @ MMU enabled?
++ moveq \rx, #0xA0000000 @ physical base address
++ movne \rx, #0xf0000000 @ virtual base
++ addne \rx, \rx, #0xA0000000 >> 4
++ .endm
++
++ .macro senduart,rd,rx
++ strb \rd, [\rx, #UART01x_DR]
++ .endm
++
++ .macro waituart,rd,rx
++1001: ldr \rd, [\rx, #0x18] @ UARTFLG
++ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
++ bne 1001b
++ .endm
++
++ .macro busyuart,rd,rx
++1001: ldr \rd, [\rx, #0x18] @ UARTFLG
++ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
++ bne 1001b
++ .endm
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/debug.h
@@ -0,0 +1,148 @@
+/*
+ * linux/include/asm-arm/arch-nomadik/debug-nomadik.h
+ * Description: Nomadik debug message strategy include file
+ *
+ * Reference: Documentation/arm/STM-Nomadik/debug_strategy.txt
-+ *
++ *
+ * Author : ST Microelectronics
-+ *
++ *
+ * ---------------------------------------------------------------------
+ */
+
+#endif /* __INC_DBG_H */
+
+/* End of file - debug.h */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S
---- linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,38 @@
-+/* linux/include/asm-arm/arch-integrator/debug-macro.S
-+ *
-+ * Debugging macro include header
-+ *
-+ * Copyright (C) 1994-1999 Russell King
-+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+*/
-+
-+#include <linux/amba/serial.h>
-+
-+ .macro addruart,rx
-+ mrc p15, 0, \rx, c1, c0
-+ tst \rx, #1 @ MMU enabled?
-+ moveq \rx, #0xA0000000 @ physical base address
-+ movne \rx, #0xf0000000 @ virtual base
-+ addne \rx, \rx, #0xA0000000 >> 4
-+ .endm
-+
-+ .macro senduart,rd,rx
-+ strb \rd, [\rx, #UART01x_DR]
-+ .endm
-+
-+ .macro waituart,rd,rx
-+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
-+ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
-+ bne 1001b
-+ .endm
-+
-+ .macro busyuart,rd,rx
-+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
-+ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
-+ bne 1001b
-+ .endm
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/defs.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/defs.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/defs.h 2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/defs.h
@@ -0,0 +1,245 @@
+/*
+ * include/asm/arch/defs.h
+
+#ifndef __ASSEMBLY__
+/*
-+ * Type definition
++ * Type definition
+ */
+#ifndef BITS64 /*to remove conflict with arch/arm/nwfpe/ARM-gcc.h*/
+typedef unsigned char uint8;
+
+/*
+ * 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.
+ */
+
+} version_t;
+
+/*
-+ * Keyword definition
++ * Keyword definition
+ */
+#ifndef NULL
+#define NULL (0)
+#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
+ *
+
+#include <asm/arch/defs.h>
+
-+#define MAX_DMA_CHANNELS 32
++#define MAX_DMA_CHANNELS 32
+/* MAX_DMA_CHANNELS can be increased upto 127 if system needs more channels */
+#define MAX_DMA_LLIS (MAX_DMA_CHANNELS*4096)
+/*
+ */
+struct dmach_lli {
+ union {
-+ struct dmach_lli * p_lli_qh;
++ struct dmach_lli * p_lli_qh;
+ dma_addr_t sadr;
+ } mem1;
+ union {
+};
+
+/**
-+ * data structure for default dma peripharal setup
++ * data structure for default dma peripharal setup
+ */
+struct dmadev_description {
+ char * id;
+};
+
+/**
-+ * data structure for chip specific interface
++ * data structure for chip specific interface
+ */
+struct dma_soc_data {
+ struct dma_struct *dma_chan;
+};
+
+/**
-+ * Figurative constants and enums used ...............
++ * Figurative constants and enums used ...............
+ */
+#define NMDK_DMACH_ENABLE 1UL
+#define NMDK_DMACH_HALT 1UL<<18
+/* ............ 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)*/
+#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
+#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
+ 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
+ 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
+ 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
+ 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
+ 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
+#include <asm/arch/board/epio.h>
+
+#endif /*__ASM_ARM_ARCH_EPIO_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h 2008-09-17 13:23:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h
@@ -0,0 +1,203 @@
+/* include/asm-arm/arch-nomadik/fsmc.h
+ *
+ 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
+} 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,
+ 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;
+
+/* 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
+};
+
+/**
-+ * 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
+#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
+#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)
+
+#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
+#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
+ *
+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;
+
+ __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
+#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
+ * 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)
+#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
+/*
+ * Below values need to be checked
+ */
-+#define MAXFIQNUM 31
++#define MAXFIQNUM 31
+#define MAXSWINUM 31
+
+#define MAX_CHIP_IRQ ( MAXIRQNUM + 1 )
+/* 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
+};
+
+#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
+#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
+};
+
+
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/msp.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp.h 2008-11-19 16:47:04.000000000 +0530
-@@ -0,0 +1,322 @@
-+/*Copyright 2006, STMicroelectronics
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#ifndef NOMADIC_MSP_HEADER
-+#define NOMADIC_MSP_HEADER
-+
-+/* Generic config struct. Use the actual values defined below for global
-+ * control register
-+ */
-+
-+struct msp_generic_config {
-+ unsigned int input_clock_freq;
-+ unsigned int rx_clock_sel;
-+ unsigned int tx_clock_sel;
-+ unsigned int srg_clock_sel;
-+ unsigned int rx_endianess;
-+ unsigned int tx_endianess;
-+ unsigned int rx_frame_sync_pol;
-+ unsigned int tx_frame_sync_pol;
-+ unsigned int rx_frame_sync_sel;
-+ unsigned int tx_frame_sync_sel;
-+ unsigned int rx_unexpect_frame_sync;
-+ unsigned int tx_unexpect_frame_sync;
-+ unsigned int rx_fifo_config;
-+ unsigned int tx_fifo_config;
-+ unsigned int spi_clk_mode;
-+ unsigned int spi_burst_mode;
-+};
-+typedef enum {
-+ MSP_REQUEST_NOT_APPLICABLE = -9,
-+ MSP_BAD_PERIHERAL_ID = -8,
-+ MSP_TRANSMISSION_ON_GOING = -7,
-+ MSP_TRANSMIT_FIFO_TIMEOUT = -6,
-+ MSP_FEATURE_NOT_SUPPORTED = -5,
-+ MSP_NON_AUTHORIZED_MODE = -4,
-+ MSP_NO_ACTIVE_IT_ERROR = -3,
-+ MSP_NOT_CONFIGURED = -2,
-+ MSP_PARAMETER_ERROR = -1,
-+ MSP_OK = 0,
-+ MSP_INTERNAL_EVENT = 1,
-+ MSP_REMAINING_PENDING_EVENTS = 2,
-+ MSP_REMAINING_FILTER_PENDING_EVENTS = 3,
-+ MSP_NO_MORE_PENDING_EVENT = 4,
-+ MSP_NO_MORE_FILTER_PENDING_EVENT = 5,
-+ MSP_NO_PENDING_EVENT_ERROR = 7
-+} t_msp_error;
-+
-+/*** Protocols ***/
-+enum {
-+ MSP_I2S_PROTOCOL,
-+ MSP_PCM_PROTOCOL,
-+ MSP_PCM_COMPAND_PROTOCOL,
-+ MSP_AC97_PROTOCOL,
-+ MSP_MASTER_SPI_PROTOCOL,
-+ MSP_SLAVE_SPI_PROTOCOL,
-+ MSP_INVALID_PROTOCOL
-+};
-+
-+/*** Sample Frequencies ***/
-+/* These are no longer required, frequencies in Hz can be used directly */
-+enum {
-+ MSP_SAMPLE_FREQ_NOT_SUPPORTED = -1,
-+ MSP_SAMPLE_FREQ_8KHZ = 8000,
-+ MSP_SAMPLE_FREQ_12KHZ = 12000,
-+ MSP_SAMPLE_FREQ_16KHZ = 16000,
-+ MSP_SAMPLE_FREQ_24KHZ = 24000,
-+ MSP_SAMPLE_FREQ_32KHZ = 32000,
-+ MSP_SAMPLE_FREQ_44KHZ = 44000,
-+ MSP_SAMPLE_FREQ_48KHZ = 48000,
-+ MSP_SAMPLE_FREQ_64KHZ = 64000,
-+ MSP_SAMPLE_FREQ_88KHZ = 88000,
-+ MSP_SAMPLE_FREQ_96KHZ = 96000,
-+ MSP_SAMPLE_FREQ_22KHZ = 22000,
-+ MSP_SAMPLE_FREQ_11KHZ = 11000
-+};
-+
-+/*** Input Frequencies ***/
-+/* These are no longer required, frequencies in Hz can be used directly */
-+typedef enum {
-+
-+ MSP_INPUT_FREQ_1MHZ = 1000,
-+ MSP_INPUT_FREQ_2MHZ = 2000,
-+ MSP_INPUT_FREQ_3MHZ = 3000,
-+ MSP_INPUT_FREQ_4MHZ = 4000,
-+ MSP_INPUT_FREQ_5MHZ = 5000,
-+ MSP_INPUT_FREQ_6MHZ = 6000,
-+ MSP_INPUT_FREQ_8MHZ = 8000,
-+ MSP_INPUT_FREQ_11MHZ = 11000,
-+ MSP_INPUT_FREQ_12MHZ = 12000,
-+ MSP_INPUT_FREQ_16MHZ = 16000,
-+ MSP_INPUT_FREQ_22MHZ = 22000,
-+ MSP_INPUT_FREQ_24MHZ = 24000,
-+ MSP_INPUT_FREQ_48MHZ = 48000
-+
-+} t_msp_in_clock_freq;
-+
-+#define MSP_INPUT_FREQ_APB 48000000
-+
-+/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono),
-+ * 32 bits accesses (stereo).
-+ ***/
-+enum
-+{
-+ MSP_MONO,
-+ MSP_STEREO
-+};
-+
-+/* Direction (Transmit/Receive mode) */
-+enum {
-+ MSP_TRANSMIT_MODE,
-+ MSP_RECEIVE_MODE,
-+ MSP_BOTH_T_R_MODE
-+};
-+
-+/* Dma mode should be used for large transfers,
-+ * polling mode should be used for transfers of a few bytes
-+ */
-+enum {
-+ MSP_DMA_MODE,
-+ MSP_POLLING_MODE,
-+ MSP_INTERRUPT_MODE
-+};
-+
-+/* User client for the MSP */
-+typedef enum {
-+ MSP_NO_USER = 0,
-+ MSP_USER_SPI,
-+ MSP_USER_ALSA,
-+ MSP_USER_SAA,
-+}t_msp_user;
-+
-+/*Flag structure for MSPx*/
-+typedef struct {
-+ struct semaphore lock;
-+ t_msp_user user;
-+}msp_flag ;
-+
-+
-+/* Transmit and receive configuration register */
-+#define MSP_BIG_ENDIAN 0x00000000
-+#define MSP_LITTLE_ENDIAN 0x00001000
-+#define MSP_UNEXPECTED_FS_ABORT 0x00000000
-+#define MSP_UNEXPECTED_FS_IGNORE 0x00008000
-+#define MSP_NON_MODE_BIT_MASK 0x00009000
-+
-+/* Global configuration register
-+--------------------------------*/
-+#define RX_ENABLE 0x00000001
-+#define RX_FIFO_ENABLE 0x00000002
-+#define RX_SYNC_SRG 0x00000010
-+#define RX_CLK_POL_RISING 0x00000020
-+#define RX_CLK_SEL_SRG 0x00000040
-+#define TX_ENABLE 0x00000100
-+#define TX_FIFO_ENABLE 0x00000200
-+#define TX_SYNC_SRG_PROG 0x00001800
-+#define TX_CLK_POL_RISING 0x00002000
-+#define TX_CLK_SEL_SRG 0x00004000
-+#define TX_EXTRA_DELAY_ENABLE 0x00008000
-+#define SRG_ENABLE 0x00010000
-+#define FRAME_GEN_ENABLE 0x00100000
-+#define SRG_CLK_SEL_APB 0x00000000
-+#define RX_FIFO_SYNC_HI 0x00000000
-+#define TX_FIFO_SYNC_HI 0x00000000
-+#define SPI_CLK_MODE_NORMAL 0x00000000
-+
-+/* SPI Clock Modes enumertion
-+ * SPI clock modes of MSP provides compatibility with
-+ * the SPI protocol.MSP supports 2 SPI transfer formats.
-+ * MSP_ZERO_DELAY_SPI_MODE:MSP transmits data over Tx/Rx
-+ * Lines immediately after MSPTCK/MSPRCK rising/falling edge.
-+ * MSP_HALF_CYCLE_DELY_SPI_MODE:MSP transmits data one-half cycle
-+ * ahead of the rising/falling edge of the MSPTCK
-+ */
-+enum {
-+ MSP_NON_SPI_PROTOCOL = 0,
-+ MSP_ZERO_DELAY_SPI_MODE = 2,
-+ MSP_HALF_CYCLE_DELY_SPI_MODE = 3
-+};
-+
-+#define MSP_FRAME_SIZE_AUTO -1
-+
-+enum msp_data_size{
-+ MSP_DATA_SIZE_DEFAULT = -1,
-+ MSP_DATA_SIZE_8BIT,
-+ MSP_DATA_SIZE_10BIT,
-+ MSP_DATA_SIZE_12BIT,
-+ MSP_DATA_SIZE_14BIT,
-+ MSP_DATA_SIZE_16BIT,
-+ MSP_DATA_SIZE_20BIT,
-+ MSP_DATA_SIZE_24BIT,
-+ MSP_DATA_SIZE_32BIT,
-+};
-+
-+#define MSP_I2S_SIMPLE_CONFIG { \
-+ MSP_INPUT_FREQ_APB, \
-+ RX_CLK_SEL_SRG, \
-+ TX_CLK_SEL_SRG, \
-+ SRG_CLK_SEL_APB, \
-+ MSP_BIG_ENDIAN, \
-+ MSP_BIG_ENDIAN, \
-+ RX_FIFO_SYNC_LOW, \
-+ TX_FIFO_SYNC_LOW, \
-+ RX_SYNC_SRG, \
-+ TX_SYNC_SRG_PROG, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ RX_FIFO_ENABLE, \
-+ TX_FIFO_ENABLE, \
-+ SPI_CLK_MODE_NORMAL, \
-+ SPI_BURST_MODE_DISABLE \
-+}
-+
-+#define MSP_PCM_SIMPLE_CONFIG { \
-+ MSP_INPUT_FREQ_APB, \
-+ RX_CLK_SEL_SRG, \
-+ TX_CLK_SEL_SRG, \
-+ SRG_CLK_SEL_APB, \
-+ MSP_BIG_ENDIAN, \
-+ MSP_BIG_ENDIAN, \
-+ RX_FIFO_SYNC_HI, \
-+ TX_FIFO_SYNC_HI, \
-+ RX_SYNC_SRG, \
-+ TX_SYNC_SRG_AUTO, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ RX_FIFO_ENABLE, \
-+ TX_FIFO_ENABLE, \
-+ SPI_CLK_MODE_NORMAL, \
-+ SPI_BURST_MODE_DISABLE \
-+}
-+
-+#define MSP_MASTER_SPI_SIMPLE_CONFIG { \
-+ MSP_INPUT_FREQ_APB, \
-+ RX_CLK_SEL_SRG, \
-+ TX_CLK_SEL_SRG, \
-+ SRG_CLK_SEL_APB, \
-+ MSP_BIG_ENDIAN, \
-+ MSP_BIG_ENDIAN, \
-+ RX_FIFO_SYNC_LOW, \
-+ TX_FIFO_SYNC_LOW, \
-+ RX_SYNC_SRG, \
-+ TX_SYNC_SRG_AUTO, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ RX_FIFO_ENABLE, \
-+ TX_FIFO_ENABLE, \
-+ SPI_CLK_MODE_ZERO_DLY, \
-+ SPI_BURST_MODE_DISABLE \
-+}
-+
-+#define MSP_SLAVE_SPI_SIMPLE_CONFIG { \
-+ MSP_INPUT_FREQ_APB, \
-+ RX_CLK_SEL_EXT, \
-+ TX_CLK_SEL_EXT, \
-+ SRG_CLK_SEL_APB, \
-+ MSP_BIG_ENDIAN, \
-+ MSP_BIG_ENDIAN, \
-+ RX_FIFO_SYNC_LOW, \
-+ TX_FIFO_SYNC_LOW, \
-+ RX_SYNC_EXT, \
-+ TX_SYNC_EXT, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ MSP_UNEXPECTED_FS_IGNORE, \
-+ RX_FIFO_ENABLE, \
-+ TX_FIFO_ENABLE, \
-+ SPI_CLK_MODE_ZERO_DLY, \
-+ SPI_BURST_MODE_DISABLE \
-+}
-+
-+#ifdef __KERNEL__
-+/* exported functions */
-+#include<linux/types.h>
-+int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user);
-+int nomadik_msp_send_data(int msp, void *data, size_t bytes);
-+int nomadik_msp_receive_data(int msp, void *data, size_t bytes);
-+int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
-+ void *rxdata, size_t rxbytes);
-+int nomadik_msp_enable(int msp, int direction, int work_mode,
-+ int protocol, int frame_freq, int frame_size,
-+ enum msp_data_size data_size, t_msp_user user);
-+int nomadik_msp_disable(int msp, int direction, t_msp_user user);
-+void nomadik_msp_flush_input(int msp);
-+#endif
-+
-+/***************************************************************************************
-+ *
-+ * User space interface starts here. This is intended for testing only.
-+ *
-+ ***************************************************************************************/
-+struct msp_user_enable {
-+ int direction;
-+ int work_mode;
-+ int protocol;
-+ int frame_freq;
-+ int frame_size;
-+ enum msp_data_size data_size;
-+};
-+
-+#include <linux/ioctl.h>
-+
-+#define MSP_IOC_MAGIC 'M'
-+#define MSP_CONFIGURE _IOW(MSP_IOC_MAGIC, 0, struct msp_generic_config)
-+#define MSP_ENABLE _IOW(MSP_IOC_MAGIC, 1, struct msp_user_enable)
-+#define MSP_DISABLE _IOW(MSP_IOC_MAGIC, 2, int)
-+
-+#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h
@@ -0,0 +1,343 @@
+/*
+ * arch/arm/mach-nomadik/msp-spi.h
+
+
+/*#######################################################################
-+ MSP Interrupt related Macros
++ MSP Interrupt related Macros
+#########################################################################
+ */
+#define DISABLE_ALL_MSP_INTERRUPTS 0x0
+#define CLEAR_ALL_MSP_INTERRUPTS 0xEE
+
+/*#######################################################################
-+ Default MSP Register Values
++ Default MSP Register Values
+#########################################################################
+ */
+
+ )
+
+#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/msp.h
+@@ -0,0 +1,322 @@
++/*Copyright 2006, STMicroelectronics
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef NOMADIC_MSP_HEADER
++#define NOMADIC_MSP_HEADER
++
++/* Generic config struct. Use the actual values defined below for global
++ * control register
++ */
++
++struct msp_generic_config {
++ unsigned int input_clock_freq;
++ unsigned int rx_clock_sel;
++ unsigned int tx_clock_sel;
++ unsigned int srg_clock_sel;
++ unsigned int rx_endianess;
++ unsigned int tx_endianess;
++ unsigned int rx_frame_sync_pol;
++ unsigned int tx_frame_sync_pol;
++ unsigned int rx_frame_sync_sel;
++ unsigned int tx_frame_sync_sel;
++ unsigned int rx_unexpect_frame_sync;
++ unsigned int tx_unexpect_frame_sync;
++ unsigned int rx_fifo_config;
++ unsigned int tx_fifo_config;
++ unsigned int spi_clk_mode;
++ unsigned int spi_burst_mode;
++};
++typedef enum {
++ MSP_REQUEST_NOT_APPLICABLE = -9,
++ MSP_BAD_PERIHERAL_ID = -8,
++ MSP_TRANSMISSION_ON_GOING = -7,
++ MSP_TRANSMIT_FIFO_TIMEOUT = -6,
++ MSP_FEATURE_NOT_SUPPORTED = -5,
++ MSP_NON_AUTHORIZED_MODE = -4,
++ MSP_NO_ACTIVE_IT_ERROR = -3,
++ MSP_NOT_CONFIGURED = -2,
++ MSP_PARAMETER_ERROR = -1,
++ MSP_OK = 0,
++ MSP_INTERNAL_EVENT = 1,
++ MSP_REMAINING_PENDING_EVENTS = 2,
++ MSP_REMAINING_FILTER_PENDING_EVENTS = 3,
++ MSP_NO_MORE_PENDING_EVENT = 4,
++ MSP_NO_MORE_FILTER_PENDING_EVENT = 5,
++ MSP_NO_PENDING_EVENT_ERROR = 7
++} t_msp_error;
++
++/*** Protocols ***/
++enum {
++ MSP_I2S_PROTOCOL,
++ MSP_PCM_PROTOCOL,
++ MSP_PCM_COMPAND_PROTOCOL,
++ MSP_AC97_PROTOCOL,
++ MSP_MASTER_SPI_PROTOCOL,
++ MSP_SLAVE_SPI_PROTOCOL,
++ MSP_INVALID_PROTOCOL
++};
++
++/*** Sample Frequencies ***/
++/* These are no longer required, frequencies in Hz can be used directly */
++enum {
++ MSP_SAMPLE_FREQ_NOT_SUPPORTED = -1,
++ MSP_SAMPLE_FREQ_8KHZ = 8000,
++ MSP_SAMPLE_FREQ_12KHZ = 12000,
++ MSP_SAMPLE_FREQ_16KHZ = 16000,
++ MSP_SAMPLE_FREQ_24KHZ = 24000,
++ MSP_SAMPLE_FREQ_32KHZ = 32000,
++ MSP_SAMPLE_FREQ_44KHZ = 44000,
++ MSP_SAMPLE_FREQ_48KHZ = 48000,
++ MSP_SAMPLE_FREQ_64KHZ = 64000,
++ MSP_SAMPLE_FREQ_88KHZ = 88000,
++ MSP_SAMPLE_FREQ_96KHZ = 96000,
++ MSP_SAMPLE_FREQ_22KHZ = 22000,
++ MSP_SAMPLE_FREQ_11KHZ = 11000
++};
++
++/*** Input Frequencies ***/
++/* These are no longer required, frequencies in Hz can be used directly */
++typedef enum {
++
++ MSP_INPUT_FREQ_1MHZ = 1000,
++ MSP_INPUT_FREQ_2MHZ = 2000,
++ MSP_INPUT_FREQ_3MHZ = 3000,
++ MSP_INPUT_FREQ_4MHZ = 4000,
++ MSP_INPUT_FREQ_5MHZ = 5000,
++ MSP_INPUT_FREQ_6MHZ = 6000,
++ MSP_INPUT_FREQ_8MHZ = 8000,
++ MSP_INPUT_FREQ_11MHZ = 11000,
++ MSP_INPUT_FREQ_12MHZ = 12000,
++ MSP_INPUT_FREQ_16MHZ = 16000,
++ MSP_INPUT_FREQ_22MHZ = 22000,
++ MSP_INPUT_FREQ_24MHZ = 24000,
++ MSP_INPUT_FREQ_48MHZ = 48000
++
++} t_msp_in_clock_freq;
++
++#define MSP_INPUT_FREQ_APB 48000000
++
++/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono),
++ * 32 bits accesses (stereo).
++ ***/
++enum
++{
++ MSP_MONO,
++ MSP_STEREO
++};
++
++/* Direction (Transmit/Receive mode) */
++enum {
++ MSP_TRANSMIT_MODE,
++ MSP_RECEIVE_MODE,
++ MSP_BOTH_T_R_MODE
++};
++
++/* Dma mode should be used for large transfers,
++ * polling mode should be used for transfers of a few bytes
++ */
++enum {
++ MSP_DMA_MODE,
++ MSP_POLLING_MODE,
++ MSP_INTERRUPT_MODE
++};
++
++/* User client for the MSP */
++typedef enum {
++ MSP_NO_USER = 0,
++ MSP_USER_SPI,
++ MSP_USER_ALSA,
++ MSP_USER_SAA,
++}t_msp_user;
++
++/*Flag structure for MSPx*/
++typedef struct {
++ struct semaphore lock;
++ t_msp_user user;
++}msp_flag ;
++
++
++/* Transmit and receive configuration register */
++#define MSP_BIG_ENDIAN 0x00000000
++#define MSP_LITTLE_ENDIAN 0x00001000
++#define MSP_UNEXPECTED_FS_ABORT 0x00000000
++#define MSP_UNEXPECTED_FS_IGNORE 0x00008000
++#define MSP_NON_MODE_BIT_MASK 0x00009000
++
++/* Global configuration register
++--------------------------------*/
++#define RX_ENABLE 0x00000001
++#define RX_FIFO_ENABLE 0x00000002
++#define RX_SYNC_SRG 0x00000010
++#define RX_CLK_POL_RISING 0x00000020
++#define RX_CLK_SEL_SRG 0x00000040
++#define TX_ENABLE 0x00000100
++#define TX_FIFO_ENABLE 0x00000200
++#define TX_SYNC_SRG_PROG 0x00001800
++#define TX_CLK_POL_RISING 0x00002000
++#define TX_CLK_SEL_SRG 0x00004000
++#define TX_EXTRA_DELAY_ENABLE 0x00008000
++#define SRG_ENABLE 0x00010000
++#define FRAME_GEN_ENABLE 0x00100000
++#define SRG_CLK_SEL_APB 0x00000000
++#define RX_FIFO_SYNC_HI 0x00000000
++#define TX_FIFO_SYNC_HI 0x00000000
++#define SPI_CLK_MODE_NORMAL 0x00000000
++
++/* SPI Clock Modes enumertion
++ * SPI clock modes of MSP provides compatibility with
++ * the SPI protocol.MSP supports 2 SPI transfer formats.
++ * MSP_ZERO_DELAY_SPI_MODE:MSP transmits data over Tx/Rx
++ * Lines immediately after MSPTCK/MSPRCK rising/falling edge.
++ * MSP_HALF_CYCLE_DELY_SPI_MODE:MSP transmits data one-half cycle
++ * ahead of the rising/falling edge of the MSPTCK
++ */
++enum {
++ MSP_NON_SPI_PROTOCOL = 0,
++ MSP_ZERO_DELAY_SPI_MODE = 2,
++ MSP_HALF_CYCLE_DELY_SPI_MODE = 3
++};
++
++#define MSP_FRAME_SIZE_AUTO -1
++
++enum msp_data_size{
++ MSP_DATA_SIZE_DEFAULT = -1,
++ MSP_DATA_SIZE_8BIT,
++ MSP_DATA_SIZE_10BIT,
++ MSP_DATA_SIZE_12BIT,
++ MSP_DATA_SIZE_14BIT,
++ MSP_DATA_SIZE_16BIT,
++ MSP_DATA_SIZE_20BIT,
++ MSP_DATA_SIZE_24BIT,
++ MSP_DATA_SIZE_32BIT,
++};
++
++#define MSP_I2S_SIMPLE_CONFIG { \
++ MSP_INPUT_FREQ_APB, \
++ RX_CLK_SEL_SRG, \
++ TX_CLK_SEL_SRG, \
++ SRG_CLK_SEL_APB, \
++ MSP_BIG_ENDIAN, \
++ MSP_BIG_ENDIAN, \
++ RX_FIFO_SYNC_LOW, \
++ TX_FIFO_SYNC_LOW, \
++ RX_SYNC_SRG, \
++ TX_SYNC_SRG_PROG, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ RX_FIFO_ENABLE, \
++ TX_FIFO_ENABLE, \
++ SPI_CLK_MODE_NORMAL, \
++ SPI_BURST_MODE_DISABLE \
++}
++
++#define MSP_PCM_SIMPLE_CONFIG { \
++ MSP_INPUT_FREQ_APB, \
++ RX_CLK_SEL_SRG, \
++ TX_CLK_SEL_SRG, \
++ SRG_CLK_SEL_APB, \
++ MSP_BIG_ENDIAN, \
++ MSP_BIG_ENDIAN, \
++ RX_FIFO_SYNC_HI, \
++ TX_FIFO_SYNC_HI, \
++ RX_SYNC_SRG, \
++ TX_SYNC_SRG_AUTO, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ RX_FIFO_ENABLE, \
++ TX_FIFO_ENABLE, \
++ SPI_CLK_MODE_NORMAL, \
++ SPI_BURST_MODE_DISABLE \
++}
++
++#define MSP_MASTER_SPI_SIMPLE_CONFIG { \
++ MSP_INPUT_FREQ_APB, \
++ RX_CLK_SEL_SRG, \
++ TX_CLK_SEL_SRG, \
++ SRG_CLK_SEL_APB, \
++ MSP_BIG_ENDIAN, \
++ MSP_BIG_ENDIAN, \
++ RX_FIFO_SYNC_LOW, \
++ TX_FIFO_SYNC_LOW, \
++ RX_SYNC_SRG, \
++ TX_SYNC_SRG_AUTO, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ RX_FIFO_ENABLE, \
++ TX_FIFO_ENABLE, \
++ SPI_CLK_MODE_ZERO_DLY, \
++ SPI_BURST_MODE_DISABLE \
++}
++
++#define MSP_SLAVE_SPI_SIMPLE_CONFIG { \
++ MSP_INPUT_FREQ_APB, \
++ RX_CLK_SEL_EXT, \
++ TX_CLK_SEL_EXT, \
++ SRG_CLK_SEL_APB, \
++ MSP_BIG_ENDIAN, \
++ MSP_BIG_ENDIAN, \
++ RX_FIFO_SYNC_LOW, \
++ TX_FIFO_SYNC_LOW, \
++ RX_SYNC_EXT, \
++ TX_SYNC_EXT, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ MSP_UNEXPECTED_FS_IGNORE, \
++ RX_FIFO_ENABLE, \
++ TX_FIFO_ENABLE, \
++ SPI_CLK_MODE_ZERO_DLY, \
++ SPI_BURST_MODE_DISABLE \
++}
++
++#ifdef __KERNEL__
++/* exported functions */
++#include<linux/types.h>
++int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user);
++int nomadik_msp_send_data(int msp, void *data, size_t bytes);
++int nomadik_msp_receive_data(int msp, void *data, size_t bytes);
++int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
++ void *rxdata, size_t rxbytes);
++int nomadik_msp_enable(int msp, int direction, int work_mode,
++ int protocol, int frame_freq, int frame_size,
++ enum msp_data_size data_size, t_msp_user user);
++int nomadik_msp_disable(int msp, int direction, t_msp_user user);
++void nomadik_msp_flush_input(int msp);
++#endif
++
++/***************************************************************************************
++ *
++ * User space interface starts here. This is intended for testing only.
++ *
++ ***************************************************************************************/
++struct msp_user_enable {
++ int direction;
++ int work_mode;
++ int protocol;
++ int frame_freq;
++ int frame_size;
++ enum msp_data_size data_size;
++};
++
++#include <linux/ioctl.h>
++
++#define MSP_IOC_MAGIC 'M'
++#define MSP_CONFIGURE _IOW(MSP_IOC_MAGIC, 0, struct msp_generic_config)
++#define MSP_ENABLE _IOW(MSP_IOC_MAGIC, 1, struct msp_user_enable)
++#define MSP_DISABLE _IOW(MSP_IOC_MAGIC, 2, int)
++
++#endif
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h
@@ -0,0 +1,90 @@
+ /* Header file for Multiple Timer Units.
+ * mtu.h : Defines for registering & using MTU timers */
+
+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
+#define DEFAULT_PATT0_VALUE 0x00100A00
+
+#endif /* NMDK_NAND_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h
@@ -0,0 +1,160 @@
+/*\r
+ * linux/include/asm-arm/arch-nomadik/ndk10_devices.h\r
+\r
+#endif /*__ASSEMBLY__*/\r
+#endif /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/\r
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h 2008-07-04 23:45:26.000000000 +0530
-@@ -0,0 +1,169 @@
-+/*
-+ * linux/include/asm-arm/arch-nomadik/ndk15c02_devices.h
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __ASM_ARM_ARCH_NDK15C02_DEVICES_H
-+#define __ASM_ARM_ARCH_NDK15C02_DEVICES_H
-+#ifndef __ASSEMBLY__
-+
-+#include <asm/types.h>
-+
-+/*
-+ * Macros board specific
-+ */
-+#define BOARD_IO_DESC /*nothing to define */
-+
-+/* Ethernet related board specific declaration*************************/
-+#define NOMADIK_ETH0_BASE 0x33000000 /* ETH0 Base */
-+#define SMC91111_IRQ GPIO_PIN_106
-+
-+/* MMC related board specific declaration*************************/
-+#define MMCDETECT_IRQ GPIO_PIN_119
-+#define val_volt 7 /*Value to be written at Touareg register */
-+
-+/* Touchpanel related declaration************************************/
-+#define TOUCHP_IRQ GPIO_PIN_104 /* PENIRQNO: through CPLD_IT */
-+/*#define TOUCHP_CS0 NOT_KNOWN * Chip select pin0 */
-+/*#define TOUCHP_CS1 NOT_KNOWN * Chip select pin1 */
-+#define X_DELTA_MAX 2* 10 /*Max ADC read error limit for Sub- */
-+#define Y_DELTA_MAX 2 *16 /*sequent redings */
-+#define MAX_12BIT ((1<<12)-1)
-+#define X_CORR(x, y) (x)
-+#define Y_CORR(x, y) (MAX_12BIT - y)
-+
-+/* Keypad related declaration************************************/
-+#define KEYPAD_IRQ GPIO_PIN_113
-+#define MAX_KPROW 8
-+#define MAX_KPCOL 8
-+
-+/* I2c related board specific declaration************************/
-+#define I2C_CLIENT_BUSID13 0
-+#define I2C_TOUAREG_ADAPTER 1
-+#define I2C_TOUREG_CLIENT_BUSID 0
-+#define I2C_CPLD_CLIENT_BUSID 0
-+/* Addresses for clients on this board*/
-+#define I2C_ADDR_MB 0x50 /* Motherboard*/
-+#define I2C_ADDR_UI_DB 0x51 /* UI Daughterboard*/
-+#define I2C_ADDR_IO_DB1 0x52 /* I/O Expansion daughter board 1*/
-+#define I2C_ADDR_IO_DB2 0x53 /* I/O Expansion daughter board 2*/
-+#define I2C_ADDR_CIF_CAM 0x54 /* CCIR-656 ST CIF Camera (Matisse)*/
-+#define I2C_ADDR_PP_CAM (0x08>>1) /* pepperpot camera */
-+#define I2C_ADDR_MEM_EXP 0x55 /* CCIR-656 ST CIF Camera (Matisse)*/
-+#define I2C_ADDR_AC 0x1A /* Audio codec STw5095*/
-+#define I2C_ADDR_FM_TUNER 0x62 /* FM Tuner (TDA 7701-Brite)*/
-+#define I2C_ADDR_GAS_GAUGE 0x22 /* Gas Gauge (PB700)*/
-+#define I2C_ADDR_CAM_MOD 0x45 /* LITEA Camera Module ?*/
-+#define I2C0_LP_OWNADDR 0x50
-+#define I2C1_LP_OWNADDR 0x60
-+#define I2C_ADDR_TOUAREG 0x2D
-+#define I2C_ADDR_CPLD 0x1C /* actual 0x38 and 0x39, considered only 7 msbs */
-+#define I2C_ADDR_DENC 0x20
-+
-+/* MSP related board specific declaration************************/
-+#define MSP_DATA_DELAY MSP_DELAY_0
-+#define MSP_TX_CLOCK_EDGE MSP_FALLING_EDGE
-+#define MSP_RX_CLOCK_EDGE MSP_FALLING_EDGE
-+
-+/*NORflash related board specific declaration*******************/
-+#define NMDK_FLASH_BASE 0x30000000
-+#define NMDK_FLASH_WINDOW_SIZE 32 * 1024 * 1024
-+#define NMDK_FLASH_BUSWIDTH 2
-+
-+#define GET_BANK_WIDTH(val,phys) \
-+ switch (phys) { \
-+ case NMDK_FLASH_BASE: \
-+ val = NMDK_FLASH_BUSWIDTH;\
-+ break;\
-+ default:\
-+ break;\
-+ }
-+
-+/*NANDflash related board specific declaration*******************/
-+#define BOARD_SET_NAND_DATA \
-+ nand_oob->eccbytes = 12; \
-+ nand_oob->eccpos[0] = 2; \
-+ nand_oob->eccpos[1] = 3; \
-+ nand_oob->eccpos[2] = 4; \
-+ nand_oob->eccpos[3] = 18; \
-+ nand_oob->eccpos[4] = 19; \
-+ nand_oob->eccpos[5] = 20; \
-+ nand_oob->eccpos[6] = 34; \
-+ nand_oob->eccpos[7] = 35; \
-+ nand_oob->eccpos[8] = 36; \
-+ nand_oob->eccpos[9] = 50; \
-+ nand_oob->eccpos[10] = 51; \
-+ nand_oob->eccpos[11] = 52; \
-+ this->badblockpos = 5;
-+
-+#define BOARD_SET_NAND_BADBLOCK \
-+ this->eccsteps = 4; \
-+ this->badblockpos = 5;
-+
-+/*SVA related board specific declaration*******************/
-+#define SVA_HCL_INIT_MEM_SIZE SZ_4M
-+
-+/* CPLD/EPIO related declaration************************************/
-+/* the below defination is w.r.to CPLD version 3.0.1.2 */
-+#define NOMADIK_CPLD_BASE 0x36000000 /* CPLD base */
-+
-+#define COB15_ID 0x00 /* offsets for cpld board registers */
-+#define COB15_CTRL 0x02
-+#define KEYPAD_DATA 0x04
-+#define MSP_CONF 0x06
-+#define UART_CONF 0x08
-+#define SSP_CONF 0x0A
-+#define AUX_GPO1 0x20
-+#define AUX_GPO2 0x22
-+
-+extern u16 nomadik_epio_read_i2c(int reg);
-+extern int nomadik_epio_write_i2c(u16 data, int reg);
-+#define nomadik_epio_read_cob_id() nomadik_epio_read_i2c(COB15_ID)
-+#define nomadik_epio_read_cob_ctl() nomadik_epio_read_i2c(COB15_CTRL)
-+#define nomadik_epio_read_keypad() nomadik_epio_read_i2c(KEYPAD_DATA)
-+#define nomadik_epio_read_msp_conf() nomadik_epio_read_i2c(MSP_CONF)
-+#define nomadik_epio_read_uart_conf() nomadik_epio_read_i2c(UART_CONF)
-+#define nomadik_epio_read_ssp_conf() nomadik_epio_read_i2c(SSP_CONF)
-+#define nomadik_epio_read_aux_gpo1() nomadik_epio_read_i2c(AUX_GPO1)
-+#define nomadik_epio_read_aux_gpo2() nomadik_epio_read_i2c(AUX_GPO2)
-+#define nomadik_epio_write_cob_ctl(x) nomadik_epio_write_i2c((uint16)x,COB15_CTRL)
-+#define nomadik_epio_write_keypad(x) nomadik_epio_write_i2c((uint16)x,KEYPAD_DATA)
-+#define nomadik_epio_write_msp_conf(x) nomadik_epio_write_i2c((uint16)x,MSP_CONF)
-+#define nomadik_epio_write_uart_conf(x) nomadik_epio_write_i2c((uint16)x,UART_CONF)
-+#define nomadik_epio_write_ssp_conf(x) nomadik_epio_write_i2c((uint16)x,SSP_CONF)
-+#define nomadik_epio_write_aux_gpo1(x) nomadik_epio_write_i2c((uint16)x,AUX_GPO1)
-+#define nomadik_epio_write_aux_gpo2(x) nomadik_epio_write_i2c((uint16)x,AUX_GPO2)
-+
-+/*CPLD Version abstraction constants */
-+#define COB_REV_BITS 0x7000 /*numeric field */
-+#define COB_REV_BITS_POS 12 /*need to roate this much times */
-+#define COB_REV_SUBBITS 0x0000 /*decimal field */
-+#define COB_REV_SUBBITS_POS 0 /*need to roate this much times */
-+#define CPLD_REV_BITS 0x0FF0 /*numeric field */
-+#define CPLD_REV_BITS_POS 4 /*need to roate this much times */
-+#define CPLD_REV_SUBBITS 0x000F /*decimal field */
-+
-+/* Bits defination for NDK15_CTRL (COB_CTRL) register */
-+#define CPLD_GPIO34 0x0200 /*(1)CPLD sent CC_PWRDETECTn */
-+#define BT_WAKEUP_GPO1 0x0100 /*(1)from AUX_GPO1 CPLD register, bit (0)*/
-+#define DEEPSLEEP_CLK_GPIO106 0x00c0 /*(00)from Nomadik GPIO106 */
-+#define DEEPSLEEP_CLK_GPIO49 0x0040 /*(01)from Nomadik GPIO49 */
-+#define DEEPSLEEP_CLK_GPO1 0x00c0 /*(11)from AUX_GPO1 CPLD register, bit (14)*/
-+#define GPIO106_LAN_IT 0x0030 /*(00) fron ethernet controller*/
-+#define GPIO106_PWRDET 0x0010 /*(01) fron CC_PWRDETECTn(Charge controller)*/
-+#define GPIO106_PM_ITWK 0x0020 /*(10) fron PM_IT_WKUP(Touareg USB insertion)*/
-+#define GPIO106_DIS 0x0030 /*(11) High Z*/
-+#define HPI_GPIO_DIS 0x000c /*(11) selection for HPI_GPIO disabled*/
-+#define BIOS_TCHSCR 0x0002
-+#define USER_LED0 0x0001 /*(1)user led0 on */
-+
-+/* Bits defination for UART_CONF register */
-+#define DBG_UART4W 0x0200 /*(1) select 4 number of wires on the UART interface*/
-+#define DBG_UART0 0x0400 /*(1X00) Enable the UART0 link for the debug RS232 connector */
-+#define DBG_UART1 0x0480 /*(1X01) Enable the UART1 link for the debug RS232 connector */
-+#define DBG_UART2 0x0580 /*(1X11) Enable the UART2 link for the debug RS232 connector */
-+#define MD_UART0 0x0040 /*(1X00) Enable the UART0 link for peripheral in expansion connector (Modem
-\ No newline at end of file
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h
@@ -0,0 +1,248 @@
+/*\r
+ * linux/include/asm-arm/arch-nomadik/ndk15_devices.h\r
+\r
+#endif /*__ASSEMBLY__*/\r
+#endif /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/\r
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h 2008-11-24 14:06:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h
+@@ -0,0 +1,169 @@
++/*
++ * linux/include/asm-arm/arch-nomadik/ndk15c02_devices.h
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef __ASM_ARM_ARCH_NDK15C02_DEVICES_H
++#define __ASM_ARM_ARCH_NDK15C02_DEVICES_H
++#ifndef __ASSEMBLY__
++
++#include <asm/types.h>
++
++/*
++ * Macros board specific
++ */
++#define BOARD_IO_DESC /*nothing to define */
++
++/* Ethernet related board specific declaration*************************/
++#define NOMADIK_ETH0_BASE 0x33000000 /* ETH0 Base */
++#define SMC91111_IRQ GPIO_PIN_106
++
++/* MMC related board specific declaration*************************/
++#define MMCDETECT_IRQ GPIO_PIN_119
++#define val_volt 7 /*Value to be written at Touareg register */
++
++/* Touchpanel related declaration************************************/
++#define TOUCHP_IRQ GPIO_PIN_104 /* PENIRQNO: through CPLD_IT */
++/*#define TOUCHP_CS0 NOT_KNOWN * Chip select pin0 */
++/*#define TOUCHP_CS1 NOT_KNOWN * Chip select pin1 */
++#define X_DELTA_MAX 2* 10 /*Max ADC read error limit for Sub- */
++#define Y_DELTA_MAX 2 *16 /*sequent redings */
++#define MAX_12BIT ((1<<12)-1)
++#define X_CORR(x, y) (x)
++#define Y_CORR(x, y) (MAX_12BIT - y)
++
++/* Keypad related declaration************************************/
++#define KEYPAD_IRQ GPIO_PIN_113
++#define MAX_KPROW 8
++#define MAX_KPCOL 8
++
++/* I2c related board specific declaration************************/
++#define I2C_CLIENT_BUSID13 0
++#define I2C_TOUAREG_ADAPTER 1
++#define I2C_TOUREG_CLIENT_BUSID 0
++#define I2C_CPLD_CLIENT_BUSID 0
++/* Addresses for clients on this board*/
++#define I2C_ADDR_MB 0x50 /* Motherboard*/
++#define I2C_ADDR_UI_DB 0x51 /* UI Daughterboard*/
++#define I2C_ADDR_IO_DB1 0x52 /* I/O Expansion daughter board 1*/
++#define I2C_ADDR_IO_DB2 0x53 /* I/O Expansion daughter board 2*/
++#define I2C_ADDR_CIF_CAM 0x54 /* CCIR-656 ST CIF Camera (Matisse)*/
++#define I2C_ADDR_PP_CAM (0x08>>1) /* pepperpot camera */
++#define I2C_ADDR_MEM_EXP 0x55 /* CCIR-656 ST CIF Camera (Matisse)*/
++#define I2C_ADDR_AC 0x1A /* Audio codec STw5095*/
++#define I2C_ADDR_FM_TUNER 0x62 /* FM Tuner (TDA 7701-Brite)*/
++#define I2C_ADDR_GAS_GAUGE 0x22 /* Gas Gauge (PB700)*/
++#define I2C_ADDR_CAM_MOD 0x45 /* LITEA Camera Module ?*/
++#define I2C0_LP_OWNADDR 0x50
++#define I2C1_LP_OWNADDR 0x60
++#define I2C_ADDR_TOUAREG 0x2D
++#define I2C_ADDR_CPLD 0x1C /* actual 0x38 and 0x39, considered only 7 msbs */
++#define I2C_ADDR_DENC 0x20
++
++/* MSP related board specific declaration************************/
++#define MSP_DATA_DELAY MSP_DELAY_0
++#define MSP_TX_CLOCK_EDGE MSP_FALLING_EDGE
++#define MSP_RX_CLOCK_EDGE MSP_FALLING_EDGE
++
++/*NORflash related board specific declaration*******************/
++#define NMDK_FLASH_BASE 0x30000000
++#define NMDK_FLASH_WINDOW_SIZE 32 * 1024 * 1024
++#define NMDK_FLASH_BUSWIDTH 2
++
++#define GET_BANK_WIDTH(val,phys) \
++ switch (phys) { \
++ case NMDK_FLASH_BASE: \
++ val = NMDK_FLASH_BUSWIDTH;\
++ break;\
++ default:\
++ break;\
++ }
++
++/*NANDflash related board specific declaration*******************/
++#define BOARD_SET_NAND_DATA \
++ nand_oob->eccbytes = 12; \
++ nand_oob->eccpos[0] = 2; \
++ nand_oob->eccpos[1] = 3; \
++ nand_oob->eccpos[2] = 4; \
++ nand_oob->eccpos[3] = 18; \
++ nand_oob->eccpos[4] = 19; \
++ nand_oob->eccpos[5] = 20; \
++ nand_oob->eccpos[6] = 34; \
++ nand_oob->eccpos[7] = 35; \
++ nand_oob->eccpos[8] = 36; \
++ nand_oob->eccpos[9] = 50; \
++ nand_oob->eccpos[10] = 51; \
++ nand_oob->eccpos[11] = 52; \
++ this->badblockpos = 5;
++
++#define BOARD_SET_NAND_BADBLOCK \
++ this->eccsteps = 4; \
++ this->badblockpos = 5;
++
++/*SVA related board specific declaration*******************/
++#define SVA_HCL_INIT_MEM_SIZE SZ_4M
++
++/* CPLD/EPIO related declaration************************************/
++/* the below defination is w.r.to CPLD version 3.0.1.2 */
++#define NOMADIK_CPLD_BASE 0x36000000 /* CPLD base */
++
++#define COB15_ID 0x00 /* offsets for cpld board registers */
++#define COB15_CTRL 0x02
++#define KEYPAD_DATA 0x04
++#define MSP_CONF 0x06
++#define UART_CONF 0x08
++#define SSP_CONF 0x0A
++#define AUX_GPO1 0x20
++#define AUX_GPO2 0x22
++
++extern u16 nomadik_epio_read_i2c(int reg);
++extern int nomadik_epio_write_i2c(u16 data, int reg);
++#define nomadik_epio_read_cob_id() nomadik_epio_read_i2c(COB15_ID)
++#define nomadik_epio_read_cob_ctl() nomadik_epio_read_i2c(COB15_CTRL)
++#define nomadik_epio_read_keypad() nomadik_epio_read_i2c(KEYPAD_DATA)
++#define nomadik_epio_read_msp_conf() nomadik_epio_read_i2c(MSP_CONF)
++#define nomadik_epio_read_uart_conf() nomadik_epio_read_i2c(UART_CONF)
++#define nomadik_epio_read_ssp_conf() nomadik_epio_read_i2c(SSP_CONF)
++#define nomadik_epio_read_aux_gpo1() nomadik_epio_read_i2c(AUX_GPO1)
++#define nomadik_epio_read_aux_gpo2() nomadik_epio_read_i2c(AUX_GPO2)
++#define nomadik_epio_write_cob_ctl(x) nomadik_epio_write_i2c((uint16)x,COB15_CTRL)
++#define nomadik_epio_write_keypad(x) nomadik_epio_write_i2c((uint16)x,KEYPAD_DATA)
++#define nomadik_epio_write_msp_conf(x) nomadik_epio_write_i2c((uint16)x,MSP_CONF)
++#define nomadik_epio_write_uart_conf(x) nomadik_epio_write_i2c((uint16)x,UART_CONF)
++#define nomadik_epio_write_ssp_conf(x) nomadik_epio_write_i2c((uint16)x,SSP_CONF)
++#define nomadik_epio_write_aux_gpo1(x) nomadik_epio_write_i2c((uint16)x,AUX_GPO1)
++#define nomadik_epio_write_aux_gpo2(x) nomadik_epio_write_i2c((uint16)x,AUX_GPO2)
++
++/*CPLD Version abstraction constants */
++#define COB_REV_BITS 0x7000 /*numeric field */
++#define COB_REV_BITS_POS 12 /*need to roate this much times */
++#define COB_REV_SUBBITS 0x0000 /*decimal field */
++#define COB_REV_SUBBITS_POS 0 /*need to roate this much times */
++#define CPLD_REV_BITS 0x0FF0 /*numeric field */
++#define CPLD_REV_BITS_POS 4 /*need to roate this much times */
++#define CPLD_REV_SUBBITS 0x000F /*decimal field */
++
++/* Bits defination for NDK15_CTRL (COB_CTRL) register */
++#define CPLD_GPIO34 0x0200 /*(1)CPLD sent CC_PWRDETECTn */
++#define BT_WAKEUP_GPO1 0x0100 /*(1)from AUX_GPO1 CPLD register, bit (0)*/
++#define DEEPSLEEP_CLK_GPIO106 0x00c0 /*(00)from Nomadik GPIO106 */
++#define DEEPSLEEP_CLK_GPIO49 0x0040 /*(01)from Nomadik GPIO49 */
++#define DEEPSLEEP_CLK_GPO1 0x00c0 /*(11)from AUX_GPO1 CPLD register, bit (14)*/
++#define GPIO106_LAN_IT 0x0030 /*(00) fron ethernet controller*/
++#define GPIO106_PWRDET 0x0010 /*(01) fron CC_PWRDETECTn(Charge controller)*/
++#define GPIO106_PM_ITWK 0x0020 /*(10) fron PM_IT_WKUP(Touareg USB insertion)*/
++#define GPIO106_DIS 0x0030 /*(11) High Z*/
++#define HPI_GPIO_DIS 0x000c /*(11) selection for HPI_GPIO disabled*/
++#define BIOS_TCHSCR 0x0002
++#define USER_LED0 0x0001 /*(1)user led0 on */
++
++/* Bits defination for UART_CONF register */
++#define DBG_UART4W 0x0200 /*(1) select 4 number of wires on the UART interface*/
++#define DBG_UART0 0x0400 /*(1X00) Enable the UART0 link for the debug RS232 connector */
++#define DBG_UART1 0x0480 /*(1X01) Enable the UART1 link for the debug RS232 connector */
++#define DBG_UART2 0x0580 /*(1X11) Enable the UART2 link for the debug RS232 connector */
++#define MD_UART0 0x0040 /*(1X00) Enable the UART0 link for peripheral in expansion connector (Modem
+\ No newline at end of file
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h
@@ -0,0 +1,131 @@
+/*
+ * linux/include/asm-arm/arch-nomadik/nhk15_devices.h
+
+#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
+ * 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
+#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
+/*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;
+} 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 );
+
+
+#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
+#include <asm/mach/time.h>
+#include <asm/arch/debug.h>
+
-+/*
++/*
+ * Undefine/UnComment NMDK_RTT_WAKEUP if wakeup from RTC
+ * Undefine/UnComment NMDK_RTC_WAKEUP if wakeup from RTT
+ * wakeup from that device
+
+#endif
+
-+#ifdef CONFIG_NOMADIK_PM
++#ifdef CONFIG_NOMADIK_PM
+extern int nomadik_clock_enable(u32 );
+extern int nomadik_clock_disable(u32 );
+#else
+#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
+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
+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;
+/***************************************************************************/
+
+/**
-+ * whether SSP is in loopback mode or not
++ * whether SSP is in loopback mode or not
+ */
+typedef enum {
+ LOOPBACK_DISABLED,
+} 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 {
+ * @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
+ * @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)
+ 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))))
+ * @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 {
+ 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);
+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
+#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 */
+#define NMDK_SSP_CLOCK_FREQ 48000000
+
+/*#######################################################################
-+ SSP Interrupt related Macros
++ SSP Interrupt related Macros
+#########################################################################
+ */
+#define DEFAULT_SSP_REG_IMSC 0x0UL
+#define CLEAR_ALL_SSP_INTERRUPTS 0x3
+
+/*#######################################################################
-+ Default SSP Register Values
++ Default SSP Register Values
+#########################################################################
+ */
+#define DEFAULT_SSP_REG_CR0 ( \
+ 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
+#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
+#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!!)
+ */
+
+#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
+#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
+
+
+/*
-+ * 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)
+/*
+
+
+#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.
+#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.
+#define _NOMADIK_ACODEC_STW5095_H_
+
+/*---------------------------------------------------------------------
-+ * Includes
++ * Includes
+ *--------------------------------------------------------------------*/
+#include <asm/types.h>
+
+/*---------------------------------------------------------------------
-+ * Define
++ * Define
+ *--------------------------------------------------------------------*/
+
+typedef enum {
+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
+} 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. */
+};
+
+
-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
+
+ 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
+}
+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
+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
+ 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)
+
+
+
+/*
-+ * MUSBMHDRC Register map
++ * MUSBMHDRC Register map
+ */
+
+/* Common USB registers */
+
+#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 */
+
+
+/* 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
+#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
+#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
+ u8 ackwait;
+ u8 dma_channel;
+ u8 is_tx;
-+ u8 end_number;
++ u8 end_number;
+ u16 dma_counter;
+ int lch;
+ struct nomadik_udc *udc;
+ u8 end_number;
+ unsigned dma_bytes;
+ unsigned mapped:1;
-+};
++};
+
+
+#if 0
+ 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
+ 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)
+ 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
+ * 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
+#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
+#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);
#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
+#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)
#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)
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
+#else
val |= CNTL_LCDBPP16_565;
+#endif
-+ break;
+ break;
+#ifdef CONFIG_ARCH_NOMADIK
+ case 24:
+ val |= CNTL_LCDBPP24PACKED;
- break;
++ break;
+#endif
case 32:
val |= CNTL_LCDBPP24;
break;
-diff -Nauprw linux-2.6.20/include/linux/dwarf2.h ../new/linux-2.6.20/include/linux/dwarf2.h
---- linux-2.6.20/include/linux/dwarf2.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/dwarf2.h 2007-11-21 11:51:42.000000000 +0530
+ }
+
+--- /dev/null
++++ linux-2.6.20/include/linux/dwarf2-lang.h
+@@ -0,0 +1,300 @@
++#ifndef DWARF2_LANG
++#define DWARF2_LANG
++
++/*
++ * This is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2, or (at your option) any later
++ * version.
++ */
++/*
++ * This file defines macros that allow generation of DWARF debug records
++ * for asm files. This file is platform independent. Register numbers
++ * (which are about the only thing that is platform dependent) are to be
++ * supplied by a platform defined file.
++ */
++/*
++ * We need this to work for both asm and C. In asm we are using the
++ * old comment trick to concatenate while C uses the new ANSI thing.
++ * Here we have concat macro... The multi level thing is to allow and
++ * macros used in the names to be resolved prior to the cat (at which
++ * time they are no longer the same string).
++ */
++#define CAT3(a,b,c) _CAT3(a,b,c)
++#define _CAT3(a,b,c) __CAT3(a,b,c)
++#ifndef __STDC__
++#define __CAT3(a,b,c) a/**/b/**/c
++#else
++#define __CAT3(a,b,c) a##b##c
++#endif
++#ifdef __ASSEMBLY__
++#define IFC(a)
++#define IFN_C(a) a
++#define NL ;
++#define QUOTE_THIS(a) a
++#define DWARF_preamble .section .debug_frame,"",%progbits;
++#else
++#define IFC(a) a
++#define IFN_C(a)
++#define NL \n\t
++#define QUOTE_THIS(a) _QUOTE_THIS(a)
++#define _QUOTE_THIS(a) #a
++/* Don't let CPP see the " and , \042=" \054=, */
++#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits
++#endif
++
++#ifdef CONFIG_64BIT
++#define DATA_ALIGN_FACTOR 8
++#define ADDR_LOC .quad
++#else
++#define DATA_ALIGN_FACTOR 4
++#define ADDR_LOC .long
++#endif
++
++#include <linux/dwarf2-defs.h>
++/*
++ * This macro starts a debug frame section. The debug_frame describes
++ * where to find the registers that the enclosing function saved on
++ * entry.
++ *
++ * ORD is use by the label generator and should be the same as what is
++ * passed to CFI_postamble.
++ *
++ * pc, pc register gdb ordinal.
++ *
++ * code_align this is the factor used to define locations or regions
++ * where the given definitions apply. If you use labels to define these
++ * this should be 1.
++ *
++ * data_align this is the factor used to define register offsets. If
++ * you use struct offset, this should be the size of the register in
++ * bytes or the negative of that. This is how it is used: you will
++ * define a register as the reference register, say the stack pointer,
++ * then you will say where a register is located relative to this
++ * reference registers value, say 40 for register 3 (the gdb register
++ * number). The <40> will be multiplied by <data_align> to define the
++ * byte offset of the given register (3, in this example). So if your
++ * <40> is the byte offset and the reference register points at the
++ * begining, you would want 1 for the data_offset. If <40> was the 40th
++ * 4-byte element in that structure you would want 4. And if your
++ * reference register points at the end of the structure you would want
++ * a negative data_align value(and you would have to do other math as
++ * well).
++ */
++
++#define CFI_preamble(ORD, pc, code_align, data_align) \
++ DWARF_preamble NL \
++ .align DATA_ALIGN_FACTOR NL \
++ .globl CAT3(frame,_,ORD) NL \
++CAT3(frame,_,ORD): NL \
++ .long 7f-6f NL \
++6: \
++ .long DW_CIE_ID NL \
++ .byte DW_CIE_VERSION NL \
++ .byte 0 NL \
++ .uleb128 code_align NL \
++ .sleb128 data_align NL \
++ .byte pc NL
++
++/*
++ * After the above macro and prior to the CFI_postamble, you need to
++ * define the initial state. This starts with defining the reference
++ * register and, usually the pc. Here are some helper macros:
++ */
++
++#define CFA_define_reference(reg, offset) \
++ .byte DW_CFA_def_cfa NL \
++ .uleb128 reg NL \
++ .uleb128 (offset) NL
++
++#define CFA_define_offset(reg, offset) \
++ .byte (DW_CFA_offset + reg) NL \
++ .uleb128 (offset) NL
++
++#define CFA_restore(reg) \
++ .byte (DW_CFA_restore + reg) NL
++
++#define CFI_postamble() \
++ .align DATA_ALIGN_FACTOR NL \
++7: NL \
++.previous NL
++
++/*
++ * So now your code pushs stuff on the stack, you need a new location
++ * and the rules for what to do. This starts a running description of
++ * the call frame. You need to describe what changes with respect to
++ * the call registers as the location of the pc moves through the code.
++ * The following builds an FDE (fram descriptor entry?). Like the
++ * above, it has a preamble and a postamble. It also is tied to the CFI
++ * above.
++ * The preamble macro is tied to the CFI thru the first parameter. The
++ * second is the code start address and then the code end address+1.
++ */
++#define FDE_preamble(ORD, initial_address, end_address) \
++ DWARF_preamble NL \
++ .align DATA_ALIGN_FACTOR NL \
++ .long 9f-8f NL \
++8: \
++ .long CAT3(frame,_,ORD) NL \
++ ADDR_LOC initial_address NL \
++ ADDR_LOC (end_address - initial_address) NL
++
++#define FDE_postamble() \
++ .align DATA_ALIGN_FACTOR NL \
++9: NL \
++.previous NL
++
++/*
++ * That done, you can now add registers, subtract registers, move the
++ * reference and even change the reference. You can also define a new
++ * area of code the info applies to. For discontinuous bits you should
++ * start a new FDE. You may have as many as you like.
++ */
++
++/*
++ * To advance the stack address by <bytes> (0x3f max)
++ */
++
++#define CFA_advance_loc(bytes) \
++ .byte DW_CFA_advance_loc+bytes NL
++
++/*
++ * This one is good for 0xff or 255
++ */
++#define CFA_advance_loc1(bytes) \
++ .byte DW_CFA_advance_loc1 NL \
++ .byte bytes NL
++
++#define CFA_undefine_reg(reg) \
++ .byte DW_CFA_undefined NL \
++ .uleb128 reg NL
++/*
++ * With the above you can define all the register locations. But
++ * suppose the reference register moves... Takes the new offset NOT an
++ * increment. This is how esp is tracked if it is not saved.
++ */
++
++#define CFA_define_cfa_offset(offset) \
++ .byte DW_CFA_def_cfa_offset NL \
++ .uleb128 (offset) NL
++/*
++ * Or suppose you want to use a different reference register...
++ */
++#define CFA_define_cfa_register(reg) \
++ .byte DW_CFA_def_cfa_register NL \
++ .uleb128 reg NL
++
++/*
++ * If you want to mess with the stack pointer, here is the expression.
++ * The stack starts empty.
++ */
++#define CFA_def_cfa_expression \
++ .byte DW_CFA_def_cfa_expression NL \
++ .uleb128 20f-10f NL \
++10: NL
++/*
++ * This expression is to be used for other regs. The stack starts with the
++ * stack address.
++ */
++
++#define CFA_expression(reg) \
++ .byte DW_CFA_expression NL \
++ .uleb128 reg NL \
++ .uleb128 20f-10f NL \
++10: NL
++/*
++ * Here we do the expression stuff. You should code the above followed
++ * by expression OPs followed by CFA_expression_end.
++ */
++
++
++#define CFA_expression_end \
++20: NL
++
++#define CFA_exp_OP_const4s(a) \
++ .byte DW_OP_const4s NL \
++ .long a NL
++
++#define CFA_exp_OP_swap .byte DW_OP_swap NL
++#define CFA_exp_OP_dup .byte DW_OP_dup NL
++#define CFA_exp_OP_drop .byte DW_OP_drop NL
++/*
++ * All these work on the top two elements on the stack, replacing them
++ * with the result. Top comes first where it matters. True is 1, false 0.
++ */
++#define CFA_exp_OP_deref .byte DW_OP_deref NL
++#define CFA_exp_OP_and .byte DW_OP_and NL
++#define CFA_exp_OP_div .byte DW_OP_div NL
++#define CFA_exp_OP_minus .byte DW_OP_minus NL
++#define CFA_exp_OP_mod .byte DW_OP_mod NL
++#define CFA_exp_OP_neg .byte DW_OP_neg NL
++#define CFA_exp_OP_plus .byte DW_OP_plus NL
++#define CFA_exp_OP_not .byte DW_OP_not NL
++#define CFA_exp_OP_or .byte DW_OP_or NL
++#define CFA_exp_OP_xor .byte DW_OP_xor NL
++#define CFA_exp_OP_le .byte DW_OP_le NL
++#define CFA_exp_OP_ge .byte DW_OP_ge NL
++#define CFA_exp_OP_eq .byte DW_OP_eq NL
++#define CFA_exp_OP_lt .byte DW_OP_lt NL
++#define CFA_exp_OP_gt .byte DW_OP_gt NL
++#define CFA_exp_OP_ne .byte DW_OP_ne NL
++/*
++ * These take a parameter as noted
++ */
++/*
++ * Unconditional skip to loc. loc is a label (loc:)
++ */
++#define CFA_exp_OP_skip(loc) \
++ .byte DW_OP_skip NL \
++ .hword loc-.-2 NL
++/*
++ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
++ */
++#define CFA_exp_OP_bra(loc) \
++ .byte DW_OP_bra NL \
++ .hword loc-.-2 NL
++
++/*
++ * TOS += no (an unsigned number)
++ */
++#define CFA_exp_OP_plus_uconst(no) \
++ .byte DW_OP_plus_uconst NL \
++ .uleb128 no NL
++
++/*
++ * ++TOS = no (a unsigned number)
++ */
++#define CFA_exp_OP_constu(no) \
++ .byte DW_OP_constu NL \
++ .uleb128 no NL
++/*
++ * ++TOS = no (a signed number)
++ */
++#define CFA_exp_OP_consts(no) \
++ .byte DW_OP_consts NL \
++ .sleb128 no NL
++/*
++ * ++TOS = no (an unsigned byte)
++ */
++#define CFA_exp_OP_const1u(no) \
++ .byte DW_OP_const1u NL \
++ .byte no NL
++
++
++/*
++ * ++TOS = no (a address)
++ */
++#define CFA_exp_OP_addr(no) \
++ .byte DW_OP_addr NL \
++ .long no NL
++
++/*
++ * Push current frames value for "reg" + offset
++ * We take advantage of the opcode assignments to make this a litteral reg
++ * rather than use the DW_OP_bregx opcode.
++ */
++
++#define CFA_exp_OP_breg(reg,offset) \
++ .byte DW_OP_breg0+reg NL \
++ .sleb128 offset NL
++#endif
+--- /dev/null
++++ linux-2.6.20/include/linux/dwarf2.h
@@ -0,0 +1,775 @@
+/* Declarations and definitions of codes relating to the DWARF2 symbolic
+ debugging information format.
+#define DW_EH_PE_indirect 0x80
+
+#endif /* _ELF_DWARF2_H */
-diff -Nauprw linux-2.6.20/include/linux/dwarf2-lang.h ../new/linux-2.6.20/include/linux/dwarf2-lang.h
---- linux-2.6.20/include/linux/dwarf2-lang.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/dwarf2-lang.h 2007-11-21 11:51:42.000000000 +0530
-@@ -0,0 +1,300 @@
-+#ifndef DWARF2_LANG
-+#define DWARF2_LANG
-+
-+/*
-+ * This is free software; you can redistribute it and/or modify it under
-+ * the terms of the GNU General Public License as published by the Free
-+ * Software Foundation; either version 2, or (at your option) any later
-+ * version.
-+ */
-+/*
-+ * This file defines macros that allow generation of DWARF debug records
-+ * for asm files. This file is platform independent. Register numbers
-+ * (which are about the only thing that is platform dependent) are to be
-+ * supplied by a platform defined file.
-+ */
-+/*
-+ * We need this to work for both asm and C. In asm we are using the
-+ * old comment trick to concatenate while C uses the new ANSI thing.
-+ * Here we have concat macro... The multi level thing is to allow and
-+ * macros used in the names to be resolved prior to the cat (at which
-+ * time they are no longer the same string).
-+ */
-+#define CAT3(a,b,c) _CAT3(a,b,c)
-+#define _CAT3(a,b,c) __CAT3(a,b,c)
-+#ifndef __STDC__
-+#define __CAT3(a,b,c) a/**/b/**/c
-+#else
-+#define __CAT3(a,b,c) a##b##c
-+#endif
-+#ifdef __ASSEMBLY__
-+#define IFC(a)
-+#define IFN_C(a) a
-+#define NL ;
-+#define QUOTE_THIS(a) a
-+#define DWARF_preamble .section .debug_frame,"",%progbits;
-+#else
-+#define IFC(a) a
-+#define IFN_C(a)
-+#define NL \n\t
-+#define QUOTE_THIS(a) _QUOTE_THIS(a)
-+#define _QUOTE_THIS(a) #a
-+/* Don't let CPP see the " and , \042=" \054=, */
-+#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits
-+#endif
-+
-+#ifdef CONFIG_64BIT
-+#define DATA_ALIGN_FACTOR 8
-+#define ADDR_LOC .quad
-+#else
-+#define DATA_ALIGN_FACTOR 4
-+#define ADDR_LOC .long
-+#endif
-+
-+#include <linux/dwarf2-defs.h>
-+/*
-+ * This macro starts a debug frame section. The debug_frame describes
-+ * where to find the registers that the enclosing function saved on
-+ * entry.
-+ *
-+ * ORD is use by the label generator and should be the same as what is
-+ * passed to CFI_postamble.
-+ *
-+ * pc, pc register gdb ordinal.
-+ *
-+ * code_align this is the factor used to define locations or regions
-+ * where the given definitions apply. If you use labels to define these
-+ * this should be 1.
-+ *
-+ * data_align this is the factor used to define register offsets. If
-+ * you use struct offset, this should be the size of the register in
-+ * bytes or the negative of that. This is how it is used: you will
-+ * define a register as the reference register, say the stack pointer,
-+ * then you will say where a register is located relative to this
-+ * reference registers value, say 40 for register 3 (the gdb register
-+ * number). The <40> will be multiplied by <data_align> to define the
-+ * byte offset of the given register (3, in this example). So if your
-+ * <40> is the byte offset and the reference register points at the
-+ * begining, you would want 1 for the data_offset. If <40> was the 40th
-+ * 4-byte element in that structure you would want 4. And if your
-+ * reference register points at the end of the structure you would want
-+ * a negative data_align value(and you would have to do other math as
-+ * well).
-+ */
-+
-+#define CFI_preamble(ORD, pc, code_align, data_align) \
-+ DWARF_preamble NL \
-+ .align DATA_ALIGN_FACTOR NL \
-+ .globl CAT3(frame,_,ORD) NL \
-+CAT3(frame,_,ORD): NL \
-+ .long 7f-6f NL \
-+6: \
-+ .long DW_CIE_ID NL \
-+ .byte DW_CIE_VERSION NL \
-+ .byte 0 NL \
-+ .uleb128 code_align NL \
-+ .sleb128 data_align NL \
-+ .byte pc NL
-+
-+/*
-+ * After the above macro and prior to the CFI_postamble, you need to
-+ * define the initial state. This starts with defining the reference
-+ * register and, usually the pc. Here are some helper macros:
-+ */
-+
-+#define CFA_define_reference(reg, offset) \
-+ .byte DW_CFA_def_cfa NL \
-+ .uleb128 reg NL \
-+ .uleb128 (offset) NL
-+
-+#define CFA_define_offset(reg, offset) \
-+ .byte (DW_CFA_offset + reg) NL \
-+ .uleb128 (offset) NL
-+
-+#define CFA_restore(reg) \
-+ .byte (DW_CFA_restore + reg) NL
-+
-+#define CFI_postamble() \
-+ .align DATA_ALIGN_FACTOR NL \
-+7: NL \
-+.previous NL
-+
-+/*
-+ * So now your code pushs stuff on the stack, you need a new location
-+ * and the rules for what to do. This starts a running description of
-+ * the call frame. You need to describe what changes with respect to
-+ * the call registers as the location of the pc moves through the code.
-+ * The following builds an FDE (fram descriptor entry?). Like the
-+ * above, it has a preamble and a postamble. It also is tied to the CFI
-+ * above.
-+ * The preamble macro is tied to the CFI thru the first parameter. The
-+ * second is the code start address and then the code end address+1.
-+ */
-+#define FDE_preamble(ORD, initial_address, end_address) \
-+ DWARF_preamble NL \
-+ .align DATA_ALIGN_FACTOR NL \
-+ .long 9f-8f NL \
-+8: \
-+ .long CAT3(frame,_,ORD) NL \
-+ ADDR_LOC initial_address NL \
-+ ADDR_LOC (end_address - initial_address) NL
-+
-+#define FDE_postamble() \
-+ .align DATA_ALIGN_FACTOR NL \
-+9: NL \
-+.previous NL
-+
-+/*
-+ * That done, you can now add registers, subtract registers, move the
-+ * reference and even change the reference. You can also define a new
-+ * area of code the info applies to. For discontinuous bits you should
-+ * start a new FDE. You may have as many as you like.
-+ */
-+
-+/*
-+ * To advance the stack address by <bytes> (0x3f max)
-+ */
-+
-+#define CFA_advance_loc(bytes) \
-+ .byte DW_CFA_advance_loc+bytes NL
-+
-+/*
-+ * This one is good for 0xff or 255
-+ */
-+#define CFA_advance_loc1(bytes) \
-+ .byte DW_CFA_advance_loc1 NL \
-+ .byte bytes NL
-+
-+#define CFA_undefine_reg(reg) \
-+ .byte DW_CFA_undefined NL \
-+ .uleb128 reg NL
-+/*
-+ * With the above you can define all the register locations. But
-+ * suppose the reference register moves... Takes the new offset NOT an
-+ * increment. This is how esp is tracked if it is not saved.
-+ */
-+
-+#define CFA_define_cfa_offset(offset) \
-+ .byte DW_CFA_def_cfa_offset NL \
-+ .uleb128 (offset) NL
-+/*
-+ * Or suppose you want to use a different reference register...
-+ */
-+#define CFA_define_cfa_register(reg) \
-+ .byte DW_CFA_def_cfa_register NL \
-+ .uleb128 reg NL
-+
-+/*
-+ * If you want to mess with the stack pointer, here is the expression.
-+ * The stack starts empty.
-+ */
-+#define CFA_def_cfa_expression \
-+ .byte DW_CFA_def_cfa_expression NL \
-+ .uleb128 20f-10f NL \
-+10: NL
-+/*
-+ * This expression is to be used for other regs. The stack starts with the
-+ * stack address.
-+ */
-+
-+#define CFA_expression(reg) \
-+ .byte DW_CFA_expression NL \
-+ .uleb128 reg NL \
-+ .uleb128 20f-10f NL \
-+10: NL
-+/*
-+ * Here we do the expression stuff. You should code the above followed
-+ * by expression OPs followed by CFA_expression_end.
-+ */
-+
-+
-+#define CFA_expression_end \
-+20: NL
-+
-+#define CFA_exp_OP_const4s(a) \
-+ .byte DW_OP_const4s NL \
-+ .long a NL
-+
-+#define CFA_exp_OP_swap .byte DW_OP_swap NL
-+#define CFA_exp_OP_dup .byte DW_OP_dup NL
-+#define CFA_exp_OP_drop .byte DW_OP_drop NL
-+/*
-+ * All these work on the top two elements on the stack, replacing them
-+ * with the result. Top comes first where it matters. True is 1, false 0.
-+ */
-+#define CFA_exp_OP_deref .byte DW_OP_deref NL
-+#define CFA_exp_OP_and .byte DW_OP_and NL
-+#define CFA_exp_OP_div .byte DW_OP_div NL
-+#define CFA_exp_OP_minus .byte DW_OP_minus NL
-+#define CFA_exp_OP_mod .byte DW_OP_mod NL
-+#define CFA_exp_OP_neg .byte DW_OP_neg NL
-+#define CFA_exp_OP_plus .byte DW_OP_plus NL
-+#define CFA_exp_OP_not .byte DW_OP_not NL
-+#define CFA_exp_OP_or .byte DW_OP_or NL
-+#define CFA_exp_OP_xor .byte DW_OP_xor NL
-+#define CFA_exp_OP_le .byte DW_OP_le NL
-+#define CFA_exp_OP_ge .byte DW_OP_ge NL
-+#define CFA_exp_OP_eq .byte DW_OP_eq NL
-+#define CFA_exp_OP_lt .byte DW_OP_lt NL
-+#define CFA_exp_OP_gt .byte DW_OP_gt NL
-+#define CFA_exp_OP_ne .byte DW_OP_ne NL
-+/*
-+ * These take a parameter as noted
-+ */
-+/*
-+ * Unconditional skip to loc. loc is a label (loc:)
-+ */
-+#define CFA_exp_OP_skip(loc) \
-+ .byte DW_OP_skip NL \
-+ .hword loc-.-2 NL
-+/*
-+ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
-+ */
-+#define CFA_exp_OP_bra(loc) \
-+ .byte DW_OP_bra NL \
-+ .hword loc-.-2 NL
-+
-+/*
-+ * TOS += no (an unsigned number)
-+ */
-+#define CFA_exp_OP_plus_uconst(no) \
-+ .byte DW_OP_plus_uconst NL \
-+ .uleb128 no NL
-+
-+/*
-+ * ++TOS = no (a unsigned number)
-+ */
-+#define CFA_exp_OP_constu(no) \
-+ .byte DW_OP_constu NL \
-+ .uleb128 no NL
-+/*
-+ * ++TOS = no (a signed number)
-+ */
-+#define CFA_exp_OP_consts(no) \
-+ .byte DW_OP_consts NL \
-+ .sleb128 no NL
-+/*
-+ * ++TOS = no (an unsigned byte)
-+ */
-+#define CFA_exp_OP_const1u(no) \
-+ .byte DW_OP_const1u NL \
-+ .byte no NL
-+
-+
-+/*
-+ * ++TOS = no (a address)
-+ */
-+#define CFA_exp_OP_addr(no) \
-+ .byte DW_OP_addr NL \
-+ .long no NL
-+
-+/*
-+ * Push current frames value for "reg" + offset
-+ * We take advantage of the opcode assignments to make this a litteral reg
-+ * rather than use the DW_OP_bregx opcode.
-+ */
-+
-+#define CFA_exp_OP_breg(reg,offset) \
-+ .byte DW_OP_breg0+reg NL \
-+ .sleb128 offset NL
-+#endif
-diff -Nauprw linux-2.6.20/include/linux/i2c.h ../new/linux-2.6.20/include/linux/i2c.h
---- linux-2.6.20/include/linux/i2c.h 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/i2c.h 2007-11-21 11:51:42.000000000 +0530
-@@ -146,6 +146,9 @@ struct i2c_driver {
+--- linux-2.6.20.orig/include/linux/i2c.h
++++ linux-2.6.20/include/linux/i2c.h
+@@ -144,10 +144,13 @@ struct i2c_driver {
+ * function is mainly used for lookup & other admin. functions.
+ */
struct i2c_client {
unsigned int flags; /* div., see below */
unsigned short addr; /* chip address - NOTE: 7bit */
/* 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 *);
+ /* 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
+#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 */
#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
/* 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)) \
#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,
/* 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];
/* Sysfs stuff. */
struct module_kobject mkobj;
struct module_param_attrs *param_attrs;
-diff -Nauprw linux-2.6.20/include/linux/mtd/bbm.h ../new/linux-2.6.20/include/linux/mtd/bbm.h
---- linux-2.6.20/include/linux/mtd/bbm.h 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/mtd/bbm.h 2008-09-17 13:23:35.000000000 +0530
-@@ -10,6 +10,10 @@
+ struct module_attribute *modinfo_attrs;
+ const char *version;
+--- linux-2.6.20.orig/include/linux/mtd/bbm.h
++++ linux-2.6.20/include/linux/mtd/bbm.h
+@@ -8,10 +8,14 @@
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
* Copyright (c) 2000-2005
* Thomas Gleixner <tglx@linuxtronix.de>
*
*/
#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
/**
* 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;
/*
* 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
*/
+#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
};
/**
-@@ -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
* @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
* @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;
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;
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)
/* 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)
/*
* 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)
/*
* Version ID Register F002h (R)
-@@ -80,9 +82,11 @@
+ */
#define ONENAND_VERSION_PROCESS_SHIFT (8)
/*
/*
* 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)
#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;
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
+*/
+#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
#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.
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
+ 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);
+ }
+
+ 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;
+ 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;
+
+
+ /* 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;
+ }
+
+ atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1);
-+
++
+ /*
+ * Don't enter if we have hit a removed breakpoint.
+ */
+ put_packet(remcom_out_buffer);
+ emergency_sync();
+ /* Execution should not return from
-+ * machine_restart()
++ * machine_restart()
+ */
+ machine_restart(NULL);
+ kgdb_connected = 0;
+
+ /* We can't do much if this fails */
+ register_module_notifier(&kgdb_module_load_nb);
-+
++
+ kgdb_initialized = 1;
+}
+
+
+ /* 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();
+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
+ local_irq_restore(flags);
+ }
+ return NOTIFY_DONE;
-+}
-+
++}
++
+#ifdef CONFIG_KGDB_CONSOLE
+void kgdb_console_write(struct console *co, const char *s, unsigned count)
+{
+}
+
+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
/* 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);
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
+ 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.
+ */
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;
}
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 */
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;
__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;
}
}
__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;
}
__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)
__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;
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;
}
}
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) {
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;
}
}
(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;
/* 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);
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);
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;
}
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;
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,
!(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);
/* 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);
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++)
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,
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;
+ 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,
/* 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));
}
}
{
- 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
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;
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;
}
+ 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. */
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);
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:
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;
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
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]);
}
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;
}
if ((error = device_suspend(PMSG_SUSPEND))) {
printk(KERN_ERR "Some devices failed to suspend\n");
goto Finish;
-diff -Nauprw linux-2.6.20/kernel/sched.c ../new/linux-2.6.20/kernel/sched.c
---- linux-2.6.20/kernel/sched.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/sched.c 2007-11-21 11:51:42.000000000 +0530
-@@ -52,6 +52,7 @@
+ }
+ return 0;
+--- linux-2.6.20.orig/kernel/sched.c
++++ linux-2.6.20/kernel/sched.c
+@@ -50,10 +50,11 @@
+ #include <linux/syscalls.h>
+ #include <linux/times.h>
#include <linux/tsacct_kern.h>
#include <linux/kprobes.h>
#include <linux/delayacct.h>
#include <asm/tlb.h>
#include <asm/unistd.h>
-@@ -6962,6 +6963,11 @@ void __might_sleep(char *file, int line)
+
+ /*
+@@ -6964,10 +6965,15 @@ void __init sched_init(void)
+ void __might_sleep(char *file, int line)
+ {
#ifdef in_atomic
static unsigned long prev_jiffy; /* ratelimiting */
if ((in_atomic() || irqs_disabled()) &&
system_state == SYSTEM_RUNNING && !oops_in_progress) {
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
-diff -Nauprw linux-2.6.20/kernel/softlockup.c ../new/linux-2.6.20/kernel/softlockup.c
---- linux-2.6.20/kernel/softlockup.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/softlockup.c 2007-11-21 11:51:42.000000000 +0530
-@@ -13,6 +13,7 @@
+ return;
+ prev_jiffy = jiffies;
+--- linux-2.6.20.orig/kernel/softlockup.c
++++ linux-2.6.20/kernel/softlockup.c
+@@ -11,10 +11,11 @@
+ #include <linux/init.h>
+ #include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/notifier.h>
#include <linux/module.h>
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;
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
-diff -Nauprw linux-2.6.20/kernel/timer.c ../new/linux-2.6.20/kernel/timer.c
---- linux-2.6.20/kernel/timer.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/timer.c 2008-10-20 13:37:46.000000000 +0530
-@@ -33,6 +33,7 @@
+ /*
+ * This callback runs from the timer interrupt, and checks
+--- linux-2.6.20.orig/kernel/timer.c
++++ linux-2.6.20/kernel/timer.c
+@@ -31,10 +31,11 @@
+ #include <linux/time.h>
+ #include <linux/jiffies.h>
#include <linux/posix-timers.h>
#include <linux/cpu.h>
#include <linux/syscalls.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
-@@ -1207,8 +1208,15 @@ static inline void update_times(unsigned
+ #include <asm/unistd.h>
+ #include <asm/div64.h>
+@@ -1205,12 +1206,19 @@ static inline void update_times(unsigned
+ * jiffies is defined in the linker script...
+ */
void do_timer(unsigned long ticks)
{
}
#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.
+ to use NETCONSOLE in conjunction with KGDB_ETH instead of
+ KGDB_CONSOLE.
+
-diff -Nauprw linux-2.6.20/MAINTAINERS ../new/linux-2.6.20/MAINTAINERS
---- linux-2.6.20/MAINTAINERS 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/MAINTAINERS 2007-11-21 11:51:42.000000000 +0530
-@@ -1941,6 +1941,15 @@ L: linux-kernel@vger.kernel.org
- L: fastboot@osdl.org
- S: Maintained
-
-+KGDB
-+P: Tom Rini
-+P: Amit S. Kale
-+M: trini@kernel.crashing.org
-+M: amitkale@linsyssoft.com
-+W: http://sourceforge.net/projects/kgdb
-+L: kgdb-bugreport@lists.sourceforge.net
-+S: Maintained
-+
- KPROBES
- P: Prasanna S Panchamukhi
- M: prasanna@in.ibm.com
-diff -Nauprw linux-2.6.20/Makefile ../new/linux-2.6.20/Makefile
---- linux-2.6.20/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/Makefile 2008-10-20 13:37:44.000000000 +0530
-@@ -12,7 +12,7 @@ NAME = Homicidal Dwarf Hamster
-
- # Do not:
- # o use make's built-in rules and variables
--# (this increases performance and avoid hard-to-debug behavour);
-+# (this increases performance and avoids hard-to-debug behaviour);
- # o print "Entering directory ...";
- MAKEFLAGS += -rR --no-print-directory
-
-@@ -321,7 +321,7 @@ KERNELRELEASE = $(shell cat include/conf
- KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
- export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
--export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
-+export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CFLAGS CROSS_COMPILE AS LD CC
- export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
- export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
-
-@@ -497,7 +497,7 @@ CFLAGS += -fomit-frame-pointer
- endif
-
- ifdef CONFIG_DEBUG_INFO
--CFLAGS += -g
-+CFLAGS += -gdwarf-2
- endif
-
- # Force gcc to behave correct even for buggy distributions
-@@ -530,7 +530,6 @@ export INSTALL_PATH ?= /boot
- # relocations required by build roots. This is not defined in the
- # makefile but the argument can be passed to make if needed.
- #
--
- MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
- export MODLIB
-
-@@ -576,7 +575,7 @@ libs-y := $(libs-y1) $(libs-y2)
- # ---------------------------------------------------------------------------
- # vmlinux is built from the objects selected by $(vmlinux-init) and
- # $(vmlinux-main). Most are built-in.o files from top-level directories
--# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
-+# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
- # Ordering when linking is important, and $(vmlinux-init) must be first.
- #
- # vmlinux
-@@ -734,6 +733,7 @@ debug_kallsyms: .tmp_map$(last_kallsyms)
-
- endif # ifdef CONFIG_KALLSYMS
-
-+include $(srctree)/scripts/ksymhash/Makefile
- # vmlinux image - including updated kernel symbols
- vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
- ifdef CONFIG_HEADERS_CHECK
-@@ -742,6 +742,7 @@ endif
- $(call if_changed_rule,vmlinux__)
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
- $(Q)rm -f .old_version
-+ $(rule_ksymhash)
-
- # The actual objects are generated when descending,
- # make sure no implicit rule kicks in
-@@ -1482,7 +1483,12 @@ clean := -f $(if $(KBUILD_SRC),$(srctree
- endif # skip-makefile
-
- PHONY += FORCE
--FORCE:
-+include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk
-+ mkdir -p include/linux/
-+ awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h
-+
-+FORCE: include/linux/dwarf2-defs.h
-+
-
- # Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes.
- Makefile: ;
-diff -Nauprw linux-2.6.20/net/core/fib_rules.c ../new/linux-2.6.20/net/core/fib_rules.c
---- linux-2.6.20/net/core/fib_rules.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/net/core/fib_rules.c 2008-08-27 04:39:17.000000000 +0530
-@@ -1,473 +0,0 @@
--/*
-- * net/core/fib_rules.c Generic Routing Rules
-- *
-- * This program is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU General Public License as
-- * published by the Free Software Foundation, version 2.
-- *
-- * Authors: Thomas Graf <tgraf@suug.ch>
-- */
--
--#include <linux/types.h>
--#include <linux/kernel.h>
--#include <linux/list.h>
--#include <net/fib_rules.h>
--
--static LIST_HEAD(rules_ops);
--static DEFINE_SPINLOCK(rules_mod_lock);
--
--static void notify_rule_change(int event, struct fib_rule *rule,
-- struct fib_rules_ops *ops, struct nlmsghdr *nlh,
-- u32 pid);
--
--static struct fib_rules_ops *lookup_rules_ops(int family)
--{
-- struct fib_rules_ops *ops;
--
-- rcu_read_lock();
-- list_for_each_entry_rcu(ops, &rules_ops, list) {
-- if (ops->family == family) {
-- if (!try_module_get(ops->owner))
-- ops = NULL;
-- rcu_read_unlock();
-- return ops;
-- }
-- }
-- rcu_read_unlock();
--
-- return NULL;
--}
--
--static void rules_ops_put(struct fib_rules_ops *ops)
--{
-- if (ops)
-- module_put(ops->owner);
--}
--
--int fib_rules_register(struct fib_rules_ops *ops)
--{
-- int err = -EEXIST;
-- struct fib_rules_ops *o;
--
-- if (ops->rule_size < sizeof(struct fib_rule))
-- return -EINVAL;
--
-- if (ops->match == NULL || ops->configure == NULL ||
-- ops->compare == NULL || ops->fill == NULL ||
-- ops->action == NULL)
-- return -EINVAL;
--
-- spin_lock(&rules_mod_lock);
-- list_for_each_entry(o, &rules_ops, list)
-- if (ops->family == o->family)
-- goto errout;
--
-- list_add_tail_rcu(&ops->list, &rules_ops);
-- err = 0;
--errout:
-- spin_unlock(&rules_mod_lock);
--
-- return err;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_register);
--
--static void cleanup_ops(struct fib_rules_ops *ops)
--{
-- struct fib_rule *rule, *tmp;
--
-- list_for_each_entry_safe(rule, tmp, ops->rules_list, list) {
-- list_del_rcu(&rule->list);
-- fib_rule_put(rule);
-- }
--}
--
--int fib_rules_unregister(struct fib_rules_ops *ops)
--{
-- int err = 0;
-- struct fib_rules_ops *o;
--
-- spin_lock(&rules_mod_lock);
-- list_for_each_entry(o, &rules_ops, list) {
-- if (o == ops) {
-- list_del_rcu(&o->list);
-- cleanup_ops(ops);
-- goto out;
-- }
-- }
--
-- err = -ENOENT;
--out:
-- spin_unlock(&rules_mod_lock);
--
-- synchronize_rcu();
--
-- return err;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_unregister);
--
--static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
-- struct flowi *fl, int flags)
--{
-- int ret = 0;
--
-- if (rule->ifindex && (rule->ifindex != fl->iif))
-- goto out;
--
-- if ((rule->mark ^ fl->mark) & rule->mark_mask)
-- goto out;
--
-- ret = ops->match(rule, fl, flags);
--out:
-- return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
--}
--
--int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
-- int flags, struct fib_lookup_arg *arg)
--{
-- struct fib_rule *rule;
-- int err;
--
-- rcu_read_lock();
--
-- list_for_each_entry_rcu(rule, ops->rules_list, list) {
-- if (!fib_rule_match(rule, ops, fl, flags))
-- continue;
--
-- err = ops->action(rule, fl, flags, arg);
-- if (err != -EAGAIN) {
-- fib_rule_get(rule);
-- arg->rule = rule;
-- goto out;
-- }
-- }
--
-- err = -ENETUNREACH;
--out:
-- rcu_read_unlock();
--
-- return err;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_lookup);
--
--int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
--{
-- struct fib_rule_hdr *frh = nlmsg_data(nlh);
-- struct fib_rules_ops *ops = NULL;
-- struct fib_rule *rule, *r, *last = NULL;
-- struct nlattr *tb[FRA_MAX+1];
-- int err = -EINVAL;
--
-- if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
-- goto errout;
--
-- ops = lookup_rules_ops(frh->family);
-- if (ops == NULL) {
-- err = EAFNOSUPPORT;
-- goto errout;
-- }
--
-- err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy);
-- if (err < 0)
-- goto errout;
--
-- rule = kzalloc(ops->rule_size, GFP_KERNEL);
-- if (rule == NULL) {
-- err = -ENOMEM;
-- goto errout;
-- }
--
-- if (tb[FRA_PRIORITY])
-- rule->pref = nla_get_u32(tb[FRA_PRIORITY]);
--
-- if (tb[FRA_IFNAME]) {
-- struct net_device *dev;
--
-- rule->ifindex = -1;
-- nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ);
-- dev = __dev_get_by_name(rule->ifname);
-- if (dev)
-- rule->ifindex = dev->ifindex;
-- }
--
-- if (tb[FRA_FWMARK]) {
-- rule->mark = nla_get_u32(tb[FRA_FWMARK]);
-- if (rule->mark)
-- /* compatibility: if the mark value is non-zero all bits
-- * are compared unless a mask is explicitly specified.
-- */
-- rule->mark_mask = 0xFFFFFFFF;
-- }
--
-- if (tb[FRA_FWMASK])
-- rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
--
-- rule->action = frh->action;
-- rule->flags = frh->flags;
-- rule->table = frh_get_table(frh, tb);
--
-- if (!rule->pref && ops->default_pref)
-- rule->pref = ops->default_pref();
--
-- err = ops->configure(rule, skb, nlh, frh, tb);
-- if (err < 0)
-- goto errout_free;
--
-- list_for_each_entry(r, ops->rules_list, list) {
-- if (r->pref > rule->pref)
-- break;
-- last = r;
-- }
--
-- fib_rule_get(rule);
--
-- if (last)
-- list_add_rcu(&rule->list, &last->list);
-- else
-- list_add_rcu(&rule->list, ops->rules_list);
--
-- notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
-- rules_ops_put(ops);
-- return 0;
--
--errout_free:
-- kfree(rule);
--errout:
-- rules_ops_put(ops);
-- return err;
--}
--
--int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
--{
-- struct fib_rule_hdr *frh = nlmsg_data(nlh);
-- struct fib_rules_ops *ops = NULL;
-- struct fib_rule *rule;
-- struct nlattr *tb[FRA_MAX+1];
-- int err = -EINVAL;
--
-- if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
-- goto errout;
--
-- ops = lookup_rules_ops(frh->family);
-- if (ops == NULL) {
-- err = EAFNOSUPPORT;
-- goto errout;
-- }
--
-- err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy);
-- if (err < 0)
-- goto errout;
--
-- list_for_each_entry(rule, ops->rules_list, list) {
-- if (frh->action && (frh->action != rule->action))
-- continue;
--
-- if (frh->table && (frh_get_table(frh, tb) != rule->table))
-- continue;
--
-- if (tb[FRA_PRIORITY] &&
-- (rule->pref != nla_get_u32(tb[FRA_PRIORITY])))
-- continue;
--
-- if (tb[FRA_IFNAME] &&
-- nla_strcmp(tb[FRA_IFNAME], rule->ifname))
-- continue;
--
-- if (tb[FRA_FWMARK] &&
-- (rule->mark != nla_get_u32(tb[FRA_FWMARK])))
-- continue;
--
-- if (tb[FRA_FWMASK] &&
-- (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
-- continue;
--
-- if (!ops->compare(rule, frh, tb))
-- continue;
--
-- if (rule->flags & FIB_RULE_PERMANENT) {
-- err = -EPERM;
-- goto errout;
-- }
--
-- list_del_rcu(&rule->list);
-- synchronize_rcu();
-- notify_rule_change(RTM_DELRULE, rule, ops, nlh,
-- NETLINK_CB(skb).pid);
-- fib_rule_put(rule);
-- rules_ops_put(ops);
-- return 0;
-- }
--
-- err = -ENOENT;
--errout:
-- rules_ops_put(ops);
-- return err;
--}
--
--static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
-- struct fib_rule *rule)
--{
-- size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr))
-- + nla_total_size(IFNAMSIZ) /* FRA_IFNAME */
-- + nla_total_size(4) /* FRA_PRIORITY */
-- + nla_total_size(4) /* FRA_TABLE */
-- + nla_total_size(4) /* FRA_FWMARK */
-- + nla_total_size(4); /* FRA_FWMASK */
--
-- if (ops->nlmsg_payload)
-- payload += ops->nlmsg_payload(rule);
--
-- return payload;
--}
--
--static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
-- u32 pid, u32 seq, int type, int flags,
-- struct fib_rules_ops *ops)
--{
-- struct nlmsghdr *nlh;
-- struct fib_rule_hdr *frh;
--
-- nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags);
-- if (nlh == NULL)
-- return -1;
--
-- frh = nlmsg_data(nlh);
-- frh->table = rule->table;
-- NLA_PUT_U32(skb, FRA_TABLE, rule->table);
-- frh->res1 = 0;
-- frh->res2 = 0;
-- frh->action = rule->action;
-- frh->flags = rule->flags;
--
-- if (rule->ifname[0])
-- NLA_PUT_STRING(skb, FRA_IFNAME, rule->ifname);
--
-- if (rule->pref)
-- NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
--
-- if (rule->mark)
-- NLA_PUT_U32(skb, FRA_FWMARK, rule->mark);
--
-- if (rule->mark_mask || rule->mark)
-- NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask);
--
-- if (ops->fill(rule, skb, nlh, frh) < 0)
-- goto nla_put_failure;
--
-- return nlmsg_end(skb, nlh);
--
--nla_put_failure:
-- return nlmsg_cancel(skb, nlh);
--}
--
--int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
--{
-- int idx = 0;
-- struct fib_rule *rule;
-- struct fib_rules_ops *ops;
--
-- ops = lookup_rules_ops(family);
-- if (ops == NULL)
-- return -EAFNOSUPPORT;
--
-- rcu_read_lock();
-- list_for_each_entry(rule, ops->rules_list, list) {
-- if (idx < cb->args[0])
-- goto skip;
--
-- if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid,
-- cb->nlh->nlmsg_seq, RTM_NEWRULE,
-- NLM_F_MULTI, ops) < 0)
-- break;
--skip:
-- idx++;
-- }
-- rcu_read_unlock();
-- cb->args[0] = idx;
-- rules_ops_put(ops);
--
-- return skb->len;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_dump);
--
--static void notify_rule_change(int event, struct fib_rule *rule,
-- struct fib_rules_ops *ops, struct nlmsghdr *nlh,
-- u32 pid)
--{
-- struct sk_buff *skb;
-- int err = -ENOBUFS;
--
-- skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL);
-- if (skb == NULL)
-- goto errout;
--
-- err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
-- /* failure implies BUG in fib_rule_nlmsg_size() */
-- BUG_ON(err < 0);
--
-- err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
--errout:
-- if (err < 0)
-- rtnl_set_sk_err(ops->nlgroup, err);
--}
--
--static void attach_rules(struct list_head *rules, struct net_device *dev)
--{
-- struct fib_rule *rule;
--
-- list_for_each_entry(rule, rules, list) {
-- if (rule->ifindex == -1 &&
-- strcmp(dev->name, rule->ifname) == 0)
-- rule->ifindex = dev->ifindex;
-- }
--}
--
--static void detach_rules(struct list_head *rules, struct net_device *dev)
--{
-- struct fib_rule *rule;
--
-- list_for_each_entry(rule, rules, list)
-- if (rule->ifindex == dev->ifindex)
-- rule->ifindex = -1;
--}
--
--
--static int fib_rules_event(struct notifier_block *this, unsigned long event,
-- void *ptr)
--{
-- struct net_device *dev = ptr;
-- struct fib_rules_ops *ops;
--
-- ASSERT_RTNL();
-- rcu_read_lock();
--
-- switch (event) {
-- case NETDEV_REGISTER:
-- list_for_each_entry(ops, &rules_ops, list)
-- attach_rules(ops->rules_list, dev);
-- break;
--
-- case NETDEV_UNREGISTER:
-- list_for_each_entry(ops, &rules_ops, list)
-- detach_rules(ops->rules_list, dev);
-- break;
-- }
--
-- rcu_read_unlock();
--
-- return NOTIFY_DONE;
--}
--
--static struct notifier_block fib_rules_notifier = {
-- .notifier_call = fib_rules_event,
--};
--
--static int __init fib_rules_init(void)
--{
-- return register_netdevice_notifier(&fib_rules_notifier);
--}
--
--subsys_initcall(fib_rules_init);
-diff -Nauprw linux-2.6.20/net/core/netpoll.c ../new/linux-2.6.20/net/core/netpoll.c
---- linux-2.6.20/net/core/netpoll.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/net/core/netpoll.c 2007-11-21 11:51:42.000000000 +0530
-@@ -491,7 +491,10 @@ int __netpoll_rx(struct sk_buff *skb)
+--- linux-2.6.20.orig/net/core/netpoll.c
++++ linux-2.6.20/net/core/netpoll.c
+@@ -496,11 +496,14 @@ int __netpoll_rx(struct sk_buff *skb)
+ if (np->local_port && np->local_port != ntohs(uh->dest))
+ goto out;
np->rx_hook(np, ntohs(uh->source),
(char *)(uh+1),
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;
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"
+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
$< -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
$< -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
$(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"
+
+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);
+ /* 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;
+ info->is_lkm = 0;
+ /* Don't care */
+ info->base_addr = 0;
-+ }
++ }
+
+ /* Fix endianness in ELF header */
+ hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
+ 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)
+}
+
+
-diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/ksymhash/elflib.h
---- linux-2.6.20/scripts/ksymhash/elflib.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/elflib.h 2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/elflib.h
@@ -0,0 +1,142 @@
+#include <sys/stat.h>
+#include <elf.h>
+ __ksymtab_gpl_future
+ and
+ __ksymtab_strings
-+*/
++*/
+
+enum ksymtab_type {
+ KSYMTAB = 0,
+ unsigned long size;
+ Elf_Ehdr *hdr;
+ Elf_Shdr *sechdrs;
-+
++
+ unsigned char is_lkm;
+ unsigned long base_addr;
+ unsigned int unresolved;
+ 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;
+void parse_elf_finish(struct elf_info *info);
+
+
-diff -Nauprw linux-2.6.20/scripts/ksymhash/empty.c ../new/linux-2.6.20/scripts/ksymhash/empty.c
---- linux-2.6.20/scripts/ksymhash/empty.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/empty.c 2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/empty.c
@@ -0,0 +1 @@
+/* empty file to figure out endianness / word size */
-diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/scripts/ksymhash/ksymhash.c
---- linux-2.6.20/scripts/ksymhash/ksymhash.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/ksymhash.c 2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/ksymhash.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright STMicroelectronics Ltd (2008)
-+ *
++ *
+ * Author: Carmelo Amoroso <carmelo.amoroso@st.com>
+ *
+ *
+ */
-+
++
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#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;
+
+ struct kernel_symbol * sym;
+ long s_offset;
-+
++
+ if(elf->is_lkm) {
+ /*
+ * ksym->name is an offset with respect to the start of the
+ */
+ 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));
+ 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) {
+ */
+ hash_values++;
+ undef++;
-+ }
-+ }
++ }
++ }
+ }
+ }
+ elf->unresolved = undef;
-+}
++}
+
+
+int main(int argc, char **argv) {
+
+ enum ksymtab_type k;
+ struct elf_info info = { };
-+
++
+ if (!parse_elf(&info, argv[1])) {
+ exit(1);
-+ }
-+
++ }
++
+ /* Skip __ksymtab_strings and __ksymtab.hash*/
+ debug("--------------------------------------------------------------------------------\n");
+ for(k=KSYMTAB; k < KSYMTAB_ALL; k++) {
+
+ if(info.ksym_tables[k].name) {
-+
-+ /* Compute hash value for exported symbols */
++
++ /* Compute hash value for exported symbols */
+ compute_exported_hash(&info, k);
-+
-+ debug("ktable: %s [exported: %u]\n",
-+ info.ksym_tables[k].name, info.ksym_tables[k].entries);
++
++ debug("ktable: %s [exported: %u]\n",
++ info.ksym_tables[k].name, info.ksym_tables[k].entries);
+ }
-+ }
++ }
+ debug("--------------------------------------------------------------------------------\n");
+
+ compute_unresolved_hash(&info);
+ debug("Module: %s [unresolved: %u]\n", argv[1], info.unresolved);
+ debug("--------------------------------------------------------------------------------\n");
-+
++
+
+ parse_elf_finish(&info);
+ return 0;
+}
-diff -Nauprw linux-2.6.20/scripts/ksymhash/Makefile ../new/linux-2.6.20/scripts/ksymhash/Makefile
---- linux-2.6.20/scripts/ksymhash/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/Makefile 2008-10-20 13:38:35.000000000 +0530
-@@ -0,0 +1,35 @@
-+# Shared between Makefile and Makefile.modpost
-+
-+hostprogs-y += ksymhash mk_elfconfig
-+always := $(hostprogs-y) empty.o
-+
-+ksymhash-objs := ksymhash.o elflib.o
-+
-+# dependencies on generated files need to be listed explicitly
-+
-+$(obj)/ksymhash.o : $(obj)/elflib.o
-+$(obj)/elflib.o : $(obj)/elfconfig.h
-+
-+quiet_cmd_elfconfig = MKELF $@
-+ cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
-+
-+$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
-+ $(call if_changed,elfconfig)
-+
-+targets += elfconfig.h
-+
-+# Post-process vmlinux image to populate ksymtabs with GNU hash values
-+
-+quiet_cmd_ksymhash = SYMHASH
-+ cmd_ksymhash = scripts/ksymhash/ksymhash
-+
-+ifdef CONFIG_LKM_HASH
-+define rule_ksymhash
-+ $(Q)$(if $($(quiet)cmd_ksymhash), \
-+ echo ' $($(quiet)cmd_ksymhash) $@' &&) \
-+ $(cmd_ksymhash) $@
-+endef
-+else
-+define rule_ksymhash
-+endef
-+endif
-diff -Nauprw linux-2.6.20/scripts/ksymhash/mk_elfconfig.c ../new/linux-2.6.20/scripts/ksymhash/mk_elfconfig.c
---- linux-2.6.20/scripts/ksymhash/mk_elfconfig.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/mk_elfconfig.c 2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/mk_elfconfig.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+ 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);
}
}
+ 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");
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);
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
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
+ *
+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
+
+
+#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
+ */
+
+/*-----------------------------------------------------------------------------
-+ * Common Includes
++ * Common Includes
+ *---------------------------------------------------------------------------*/
+
+#include <linux/module.h>
+#define TRACE_EXIT(devname) DEBUG(4, "%s: <- " __FUNCTION__ "()\n", devname);
+
+/*----------------------------------------------------------------------------
-+ * global declarations
++ * global declarations
+ *---------------------------------------------------------------------------*/
+
+codec_configuration *nomadik_acodec_conf, *nomadik_acodec_defaultconf;
+
+/**
+ * nomadik_acodec_set_user
-+ *
++ *
+ * Set the current user for acodec.
+ */
+
+
+/**
+ * nomadik_acodec_unset_user
-+ *
++ *
+ * Unset the current user for acodec.
+ */
+
+ ("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");
+
+
+/**
+ * nomadik_acodec_deinit
-+ *
-+ * exit function for STW5094 audiocodec driver.
++ *
++ * exit function for STW5094 audiocodec driver.
+ */
+static void __exit nomadik_acodec_deinit(void)
+{
+}
+
+/**
-+* 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,
+}
+
+/**
-+* 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
+
+ }
+
-+ /* 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) {
+}
+
+/**
-+ * 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,
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+* 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)
+{
+}
+
+/**
-+* 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;
+}
+
+/**
-+* 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,
+ }
+
+ /* 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)) {
+}
+
+/**
-+* 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)
+{
+}
+
+/**
-+* 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;
+}
+
+/**
-+* 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,
+ 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) {
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+{
+
+}
+
+/**
-+ * 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)
+{
+}
+
+/**
-+ * 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)
+}
+
+/**
-+ * 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)
+}
+
+/*
-+ * 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
+}
+
+/**
-+ * 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)
+}
+
+/**
-+ * 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)
+}
+
+/*******************************************************************************
-+ * private functions
++ * private functions
+ ******************************************************************************/
+
+/* Calculate F1 or F2 from frequency given for DTMF tone generation */
+ 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)
+{
+
+
+/**
+ * nomadik_acodec_reset
-+ *
++ *
+ * Reset the global variables and clear audiocodec settings to default.
+ */
+t_codec_error reset_nomadik_acodec(void)
+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
+ *