aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-gumstix-2.6.15
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/linux/linux-gumstix-2.6.15
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
downloadopenembedded-709c4d66e0b107ca606941b988bad717c0b45d9b.tar.gz
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/linux/linux-gumstix-2.6.15')
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch13
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/arch-config.patch55
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/audio.patch454
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch1415
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch117
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch403
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/board-init.patch98
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch12
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch14
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch22
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch25
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch64
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch12
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch14
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch25
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch70
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/compact-flash.patch171
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch53
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch42
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix995
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/defconfig.patch766
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch32
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch26
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/flash.patch171
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch91
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/header.patch87
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch43
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch72
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch50
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch13
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch13
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch12
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch106
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch171
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch105
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch401
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch13
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch57
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch329
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch34
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch46
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch53
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch84
-rw-r--r--recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch704
44 files changed, 7553 insertions, 0 deletions
diff --git a/recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch b/recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch
new file mode 100644
index 0000000000..8829a0cea7
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch
@@ -0,0 +1,13 @@
+Oddly, drivers/input/input.c seems to reference a symbol which is apparently in another module but not exported.
+Index: linux-2.6.15gum/drivers/char/random.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/char/random.c
++++ linux-2.6.15gum/drivers/char/random.c
+@@ -646,6 +646,7 @@ extern void add_input_randomness(unsigne
+ add_timer_randomness(&input_timer_state,
+ (type << 4) ^ code ^ (code >> 4) ^ value);
+ }
++EXPORT_SYMBOL(add_input_randomness);
+
+ void add_interrupt_randomness(int irq)
+ {
diff --git a/recipes/linux/linux-gumstix-2.6.15/arch-config.patch b/recipes/linux/linux-gumstix-2.6.15/arch-config.patch
new file mode 100644
index 0000000000..411a117953
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/arch-config.patch
@@ -0,0 +1,55 @@
+Index: linux-2.6.15gum/arch/arm/mach-pxa/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-pxa/Kconfig
+@@ -5,6 +5,10 @@ menu "Intel PXA2xx Implementations"
+ choice
+ prompt "Select target board"
+
++config ARCH_GUMSTIX
++ bool "Gumstix Platform"
++ depends on ARCH_PXA
++
+ config ARCH_LUBBOCK
+ bool "Intel DBPXA250 Development Platform"
+ select PXA25x
+@@ -94,6 +98,27 @@ config MACH_TOSA
+ bool "Enable Sharp SL-6000x (Tosa) Support"
+ depends PXA_SHARPSL_25x
+
++choice
++ depends on ARCH_GUMSTIX
++ prompt "Gumstix Platform Version"
++ default ARCH_GUMSTIX_F
++
++config ARCH_GUMSTIX_ORIG
++ bool "Original Gumstix"
++ select PXA25x
++ help
++ The original gumstix platform, including the gs-200x and gs-400x and the waysmall
++ systems using these boards.
++
++config ARCH_GUMSTIX_F
++ bool "Gumstix-F"
++ select PXA25x
++ help
++ The updated Gumstix boards with 60-pin connector, including gs-200f, gs-400f and the
++ waysmall systems using these boards, including ws-200ax and ws-400ax.
++
++endchoice
++
+ config PXA25x
+ bool
+ help
+Index: linux-2.6.15gum/arch/arm/mach-pxa/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/Makefile
++++ linux-2.6.15gum/arch/arm/mach-pxa/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_PXA25x) += pxa25x.o
+ obj-$(CONFIG_PXA27x) += pxa27x.o
+
+ # Specific board support
++obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
+ obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+ obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
+ obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
diff --git a/recipes/linux/linux-gumstix-2.6.15/audio.patch b/recipes/linux/linux-gumstix-2.6.15/audio.patch
new file mode 100644
index 0000000000..d565b70582
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/audio.patch
@@ -0,0 +1,454 @@
+Index: linux-2.6.15gum/sound/oss/ac97_codec.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/ac97_codec.c
++++ linux-2.6.15gum/sound/oss/ac97_codec.c
+@@ -59,6 +59,9 @@
+
+ #define CODEC_ID_BUFSZ 14
+
++static int ucb1400_read_mixer(struct ac97_codec *codec, int oss_channel);
++static void ucb1400_write_mixer(struct ac97_codec *codec, int oss_channel,
++ unsigned int left, unsigned int right);
+ static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel);
+ static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
+ unsigned int left, unsigned int right);
+@@ -85,6 +88,7 @@ static int cmedia_init(struct ac97_codec
+ static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
+ static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
+ static int ucb1400_init(struct ac97_codec *codec);
++static int ucb1400_control(struct ac97_codec *codec, int on);
+
+
+ /*
+@@ -120,7 +124,7 @@ static struct ac97_ops crystal_digital_o
+ static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
+ static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL};
+ static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control};
+-static struct ac97_ops ucb1400_ops = { ucb1400_init, eapd_control, NULL };
++static struct ac97_ops ucb1400_ops = { ucb1400_init, ucb1400_control, NULL };
+
+ /* sorted by vendor/device id */
+ static const struct {
+@@ -309,6 +313,143 @@ static LIST_HEAD(codecs);
+ static LIST_HEAD(codec_drivers);
+ static DECLARE_MUTEX(codec_sem);
+
++// Values of UCB1400 register addresses
++#define AC97_UCB1400_FCR1 (0x6a)
++#define AC97_UCB1400_FCR2 (0x6c)
++// Masks for bits of interest in those registers
++#define AC97_UCB1400_BASS_BOOST_MASK (0xf << 11)
++#define AC97_UCB1400_TREB_BOOST_MASK (0x3 << 9)
++#define AC97_UCB1400_BOOST_MODE_MASK (0x3 << 7)
++// Calculate the boost mode from the register by extracting the bits, then shifting it down
++// Mode 0 == flat, 1 == minimum, 2 == minimum, 3 == maximum
++#define AC97_UCB1400_BOOST_MODE(x) (((x) & AC97_UCB1400_BOOST_MODE_MASK) >> 7)
++// Caculate the treble boost
++#define AC97_UCB1400_TREB_BOOST(x) (((x) & AC97_UCB1400_TREB_BOOST_MASK) >> 9)
++// Calculate the bass boost
++#define AC97_UCB1400_BASS_BOOST(x) (((x) & AC97_UCB1400_BASS_BOOST_MASK) >> 11)
++
++// Use a conversion table to translate from the register values to dB values
++#define AC97_UCB1400_BASS_LOOKUP(x,l) ((l)[AC97_UCB1400_BASS_BOOST(x) | (AC97_UCB1400_BOOST_MODE(x) << 4)])
++#define AC97_UCB1400_TREB_LOOKUP(x,l) ((l)[AC97_UCB1400_TREB_BOOST(x) | (AC97_UCB1400_BOOST_MODE(x) << 4)])
++
++// This lookup table is indexed by a 6 bit number:
++// Two high bits are the boost mode from teh register
++// Four low bits are from the BASS or TREB boost value in the register
++// The lookup value is the dB boost calculated from the UCB1400 spec sheet
++// The lookup values will be calculated and populated during ucb1400_init()
++static const u8 ac97_ucb1400_boost_lookup[] = {
++ [0] = 0, [1] = 0, [2] = 0, [3] = 0,
++ [4] = 0, [5] = 0, [6] = 0, [7] = 0, // flat 00
++ [8] = 0, [9] = 0, [10] = 0, [11] = 0,
++ [12] = 0, [13] = 0, [14] = 0, [15] = 0,
++
++ [16] = 0, [17] = 2, [18] = 4, [19] = 6,
++ [20] = 8, [21] = 10, [22] = 12, [23] = 14, // min 01
++ [24] = 16, [25] = 18, [26] = 18, [27] = 18,
++ [28] = 18, [29] = 18, [30] = 18, [31] = 18,
++
++ [32] = 0, [33] = 2, [34] = 4, [35] = 6,
++ [36] = 8, [37] = 10, [38] = 12, [39] = 14, // min 10
++ [40] = 16, [41] = 18, [42] = 18, [43] = 18,
++ [44] = 18, [45] = 18, [46] = 18, [47] = 18,
++
++ [48] = 0, [49] = 2, [50] = 4, [51] = 6,
++ [52] = 8, [53] = 10, [54] = 12, [55] = 14, // max 11
++ [56] = 16, [57] = 18, [58] = 20, [59] = 22,
++ [60] = 24, [61] = 24, [62] = 24, [63] = 24
++};
++
++static int ucb1400_read_mixer(struct ac97_codec *codec, int oss_channel)
++{
++ u16 val;
++
++ switch(oss_channel)
++ {
++
++ case SOUND_MIXER_BASS:
++ // Convert from the 24-dB max BASS boost level to a %age
++ val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register
++ return (AC97_UCB1400_BASS_LOOKUP(val, ac97_ucb1400_boost_lookup)*100)/24;
++
++ case SOUND_MIXER_TREBLE:
++ // Convert from the 6-dB max TREB boost level to a %age
++ val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register
++ return (AC97_UCB1400_TREB_LOOKUP(val, ac97_ucb1400_boost_lookup)*100)/6;
++
++ case SOUND_MIXER_MIC:
++ val = codec->codec_read(codec, AC97_MIC_VOL);
++ return (val & AC97_MICBOOST ? 100 : 0);
++
++ default:
++ return ac97_read_mixer(codec, oss_channel);
++ }
++}
++
++#ifndef MAX
++#define MAX(a,b) (((a)>(b)) ? (a) : (b))
++#endif
++
++static void ucb1400_write_mixer(struct ac97_codec *codec, int oss_channel,
++ unsigned int left, unsigned int right)
++{
++ u16 old_val,new_val;
++ u8 treb,bass;
++
++ switch(oss_channel)
++ {
++ case SOUND_MIXER_BASS:
++ case SOUND_MIXER_TREBLE:
++ old_val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register
++
++ // Determine which one changed, set old one to old value (or 0 if old mode was flat)
++ bass = (oss_channel==SOUND_MIXER_BASS) ?
++ (left*24)/100 : // Convert from %age to 0-24dB scale for bass
++ AC97_UCB1400_BASS_LOOKUP(old_val, ac97_ucb1400_boost_lookup);
++ treb = (oss_channel==SOUND_MIXER_TREBLE) ?
++ (left*6)/100 : // convert from %age to 0-6dB scale for bass
++ AC97_UCB1400_TREB_LOOKUP(old_val, ac97_ucb1400_boost_lookup);
++
++ // Now convert both treble and bass to values for the register.
++ // If both are 0, then use mode flat
++ // If either is non-zero, then use mode min if bass <=18
++ // Otherwise, use mode max
++ new_val = old_val & ~(AC97_UCB1400_BASS_BOOST_MASK | // First clear the bits
++ AC97_UCB1400_TREB_BOOST_MASK | // which is same as flat mode
++ AC97_UCB1400_BOOST_MODE_MASK); // with both boosts at 0
++ if(bass > 18)
++ {
++ new_val |= (3 << 7); // Set boost mode to 0b11 which is "max"
++ }
++ else if(bass > 0 || treb > 0)
++ {
++ new_val |= (1 << 7); // Set boost mode to 0b01 which is "min"
++ }
++ else
++ {
++ // Set boost mode to 0b00 which is "flat"
++ }
++
++ if(bass || treb)
++ {
++ // The value to stick in the register the boost in dB divided by 2
++ // Dividing by 2 is the same as shifting right by 1
++ // We fix overflows by anding with the mask
++ new_val |= ((bass >> 1) << 11) & AC97_UCB1400_BASS_BOOST_MASK;
++ new_val |= ((treb >> 1) << 9) & AC97_UCB1400_TREB_BOOST_MASK;
++ }
++
++ // Ok, now poke the value back to the codec
++ codec->codec_write(codec, AC97_UCB1400_FCR1, new_val);
++ break;
++
++ case SOUND_MIXER_MIC:
++ codec->codec_write(codec, AC97_MIC_VOL, (left >= 50 ? AC97_MICBOOST : 0));
++ break;
++
++ default: ac97_write_mixer(codec, oss_channel, left, right);
++ }
++}
++
+ /* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows
+ about that given mixer, and should be holding a spinlock for the card */
+ static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel)
+@@ -526,6 +667,7 @@ static int ac97_recmask_io(struct ac97_c
+ #endif
+
+ codec->codec_write(codec, AC97_RECORD_SELECT, val);
++ val = codec->codec_read(codec, AC97_RECORD_SELECT);
+
+ return 0;
+ };
+@@ -634,6 +776,8 @@ int ac97_read_proc (char *page, char **s
+ {
+ int len = 0, cap, extid, val, id1, id2;
+ struct ac97_codec *codec;
++ u8 ac97_register_query_list[] = {0x02,0x0e,0x1a,0x1c,0x26,0x2a,0x2c,0x32,0x6a,0x6c,0x00};
++ size_t i=0;
+ int is_ac97_20 = 0;
+
+ if ((codec = data) == NULL)
+@@ -702,6 +846,13 @@ int ac97_read_proc (char *page, char **s
+ codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE));
+ }
+
++ do
++ {
++ len += sprintf(page+len, "Reg. 0x%02x : 0x%04x\n",
++ ac97_register_query_list[i],
++ codec->codec_read(codec, ac97_register_query_list[i]));
++ i++;
++ } while(ac97_register_query_list[i]);
+ return len;
+ }
+
+@@ -1180,7 +1331,25 @@ static int ad1886_init(struct ac97_codec
+ }
+
+
++static int ucb1400_control(struct ac97_codec *codec, int on)
++{
++ if(on)
++ {
++ codec->codec_write(codec, AC97_POWER_CONTROL, 0x0000); // turn everything on
+
++ // Now we wait for everything to settle
++ udelay(100);
++ }
++ else
++ {
++ codec->codec_write(codec, AC97_POWER_CONTROL,
++ (1 << 11) | // PR3: Audio Vref power-down
++ (1 << 9) | // PR1: Audio DAC and output path power-down
++ (1 << 8) // PR0: Audio ADC and input path power-down
++ );
++ }
++ return 0;
++}
+
+ /*
+ * This is basically standard AC97. It should work as a default for
+@@ -1336,10 +1505,55 @@ static int pt101_init(struct ac97_codec
+
+ static int ucb1400_init(struct ac97_codec *codec)
+ {
+- codec->codec_write(codec,AC97_EXTENDED_STATUS,1);
+- //codec->codec_write(codec, 0x6a, 0x1ff7);
+- codec->codec_write(codec, 0x6a, 0x0050);
+- codec->codec_write(codec, 0x6c, 0x0030);
++ codec->supported_mixers = SOUND_MASK_VOLUME | // Specify what UCB1400 supports
++ SOUND_MASK_BASS |
++ SOUND_MASK_TREBLE |
++ SOUND_MASK_MIC |
++ SOUND_MASK_IGAIN;
++
++ codec->stereo_mixers = SOUND_MASK_VOLUME | // Specify what UCB1400 supports
++ SOUND_MASK_LINE |
++ SOUND_MASK_IGAIN;
++
++ codec->record_sources = SOUND_MASK_MIC | // Specify what UCB1400 supports
++ SOUND_MASK_LINE;
++
++ codec->read_mixer = ucb1400_read_mixer; // The UCB1400 bass and treble implementations
++ codec->write_mixer = ucb1400_write_mixer; // need special code
++
++ codec->codec_write(codec,AC97_EXTENDED_STATUS, 1); // Ensure that VRA is on
++
++ ucb1400_control(codec, 1); // Turn on DAC/ADC paths first to prevent click
++
++ codec->codec_write(codec, AC97_UCB1400_FCR1,
++ (0 << 11) | // 0 base boost
++ (0 << 9) | // 0 treble boost
++ (0 << 7) | // Mode = flat
++ (1 << 6) | // Headphones enable
++ (0 << 5) | // De-emphasis disabled
++ (1 << 4) | // DC filter enabled
++ (1 << 3) | // Hi-pass filter enabled
++ (0 << 2) | // disable interrupt signalling via GPIO_INT
++ (1 << 0) // clear ADC overflow status if set
++ );
++
++ codec->codec_write(codec, AC97_UCB1400_FCR2,
++ (0 << 15) | // must be 0
++ (0 << 13) | // must be 0
++ (1 << 12) | // ADC filter enabled
++ (0 << 10) | // must be 0
++ (0 << 4) | // Smart low power mode on neither Codec nor PLL
++ (0 << 0) // must be 0
++ );
++
++ codec->codec_write(codec, AC97_RECORD_SELECT, 0); // default source is MIC
++
++ codec->codec_write(codec, AC97_MIC_VOL, (1 << 6)); // 20dB MIC boost
++
++ codec->codec_write(codec, AC97_RECORD_GAIN, 0); // no master record gain
++
++ codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0); // no ADC to DAC loopback
++
+ return 0;
+ }
+
+@@ -1368,30 +1582,9 @@ unsigned int ac97_set_dac_rate(struct ac
+
+ if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))
+ {
+- /* Mute several registers */
+- mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
+- mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
+- phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
+- pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
+- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
+- codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
+- codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
+- codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
+-
+- /* Power down the DAC */
+- dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
+- /* Power it back up */
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+-
+- /* Restore volumes */
+- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
+- codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
+- codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
+- codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
+ }
+ return new_rate;
+ }
+@@ -1414,14 +1607,9 @@ unsigned int ac97_set_adc_rate(struct ac
+
+ if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))
+ {
+- /* Power down the ADC */
+- dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
+- /* Power it back up */
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+ }
+ return new_rate;
+ }
+Index: linux-2.6.15gum/sound/oss/pxa-ac97.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/pxa-ac97.c
++++ linux-2.6.15gum/sound/oss/pxa-ac97.c
+@@ -21,6 +21,7 @@
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/poll.h>
++#include <linux/proc_fs.h>
+ #include <linux/sound.h>
+ #include <linux/soundcard.h>
+ #include <linux/ac97_codec.h>
+@@ -55,10 +56,10 @@ static u16 pxa_ac97_read(struct ac97_cod
+ if (GSR & GSR_RDCS) {
+ GSR = GSR_RDCS; //write a 1 to clear
+ printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__);
+- }
++ }
+
+ init_completion(&CAR_completion);
+- val = *reg_addr; //valid data now but we've just started another cycle...
++ val = *reg_addr; //valid data now but we've just started another cycle...
+ wait_for_completion(&CAR_completion);
+
+ } else {
+@@ -116,7 +117,7 @@ int pxa_ac97_get(struct ac97_codec **cod
+ if (ret)
+ return ret;
+
+- CKEN |= CKEN2_AC97;
++ pxa_set_cken(CKEN2_AC97,1);
+
+ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
+ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
+@@ -134,7 +135,7 @@ int pxa_ac97_get(struct ac97_codec **cod
+ if (ret != 1) {
+ free_irq(IRQ_AC97, NULL);
+ GCR = GCR_ACLINK_OFF;
+- CKEN &= ~CKEN2_AC97;
++ pxa_set_cken(CKEN2_AC97,0);
+ return ret;
+ }
+ }
+@@ -151,7 +152,7 @@ void pxa_ac97_put(void)
+ pxa_ac97_refcount--;
+ if (!pxa_ac97_refcount) {
+ GCR = GCR_ACLINK_OFF;
+- CKEN &= ~CKEN2_AC97;
++ pxa_set_cken(CKEN2_AC97,0);
+ free_irq(IRQ_AC97, NULL);
+ }
+ up(&pxa_ac97_mutex);
+@@ -179,7 +180,7 @@ static audio_stream_t ac97_audio_in;
+ */
+ static void update_audio_in (void)
+ {
+-#if 1
++#if 0
+ long val;
+
+ /* Use the value stuffed by ac97_recmask_io()
+@@ -335,6 +336,13 @@ static int __init pxa_ac97_init(void)
+
+ update_audio_in ();
+
++ if(!proc_mkdir("driver/ucb1400",NULL)) return -EIO;
++ if(!create_proc_read_entry("driver/ucb1400/ac97",0,NULL,ac97_read_proc,&pxa_ac97_codec))
++ {
++ remove_proc_entry("driver/ucb1400",NULL);
++ return -EIO;
++ }
++
+ ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1);
+ pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1);
+
+@@ -345,6 +353,8 @@ static void __exit pxa_ac97_exit(void)
+ {
+ unregister_sound_dsp(ac97_audio_state.dev_dsp);
+ unregister_sound_mixer(pxa_ac97_codec.dev_mixer);
++ remove_proc_entry("driver/ucb1400/ac97",NULL);
++ remove_proc_entry("driver/ucb1400",NULL);
+ pxa_ac97_put();
+ }
+
+Index: linux-2.6.15gum/sound/oss/pxa-audio.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/pxa-audio.c
++++ linux-2.6.15gum/sound/oss/pxa-audio.c
+@@ -293,8 +293,6 @@ static int audio_write(struct file *file
+ audio_stream_t *s = state->output_stream;
+ int chunksize, ret = 0;
+
+- if (ppos != &file->f_pos)
+- return -ESPIPE;
+ if (s->mapped)
+ return -ENXIO;
+ if (!s->buffers && audio_setup_buf(s))
+@@ -365,8 +363,6 @@ static int audio_read(struct file *file,
+ audio_stream_t *s = state->input_stream;
+ int chunksize, ret = 0;
+
+- if (ppos != &file->f_pos)
+- return -ESPIPE;
+ if (s->mapped)
+ return -ENXIO;
+ if (!s->buffers && audio_setup_buf(s))
+@@ -684,6 +680,9 @@ static int audio_ioctl( struct inode *in
+ file->f_flags |= O_NONBLOCK;
+ return 0;
+
++ case SNDCTL_DSP_GETODELAY:
++ printk("%s: GETODELAY not implemented!\n",__FILE__);
++
+ case SNDCTL_DSP_RESET:
+ if (file->f_mode & FMODE_WRITE)
+ audio_clear_buf(os);
diff --git a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch
new file mode 100644
index 0000000000..efb7e73e15
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch
@@ -0,0 +1,1415 @@
+Index: linux-2.6.15gum/include/linux/ac97_codec.h
+===================================================================
+--- linux-2.6.15gum.orig/include/linux/ac97_codec.h
++++ linux-2.6.15gum/include/linux/ac97_codec.h
+@@ -259,7 +259,8 @@ struct ac97_codec {
+ int type;
+ u32 model;
+
+- int modem:1;
++ unsigned modem:1;
++ unsigned power:1;
+
+ struct ac97_ops *codec_ops;
+
+Index: linux-2.6.15gum/sound/oss/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/Kconfig
++++ linux-2.6.15gum/sound/oss/Kconfig
+@@ -178,6 +178,14 @@ config SOUND_MAESTRO3
+ Say Y or M if you have a sound system driven by ESS's Maestro 3
+ PCI sound chip.
+
++config SOUND_PXA_AC97
++ tristate "PXA AC97 support"
++ depends on SOUND_PRIME!=n && ARCH_PXA && SOUND
++
++config SOUND_PXA_AUDIO
++ tristate "PXA audio support"
++ depends on SOUND_PXA_AC97
++
+ config SOUND_ICH
+ tristate "Intel ICH (i8xx) audio support"
+ depends on SOUND_PRIME && PCI
+@@ -1125,6 +1133,9 @@ config SOUND_AD1980
+ tristate "AD1980 front/back switch plugin"
+ depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER
+
++config SOUND_WM97XX
++ tristate "WM97XX sound/touchscreen codec"
++
+ config SOUND_SH_DAC_AUDIO
+ tristate "SuperH DAC audio support"
+ depends on SOUND_PRIME && CPU_SH3
+Index: linux-2.6.15gum/sound/oss/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/Makefile
++++ linux-2.6.15gum/sound/oss/Makefile
+@@ -44,6 +44,8 @@ obj-$(CONFIG_SOUND_VIA82CXXX) += via82cx
+ ifeq ($(CONFIG_MIDI_VIA82CXXX),y)
+ obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o
+ endif
++obj-$(CONFIG_SOUND_PXA_AC97) += pxa-ac97.o ac97_codec.o
++obj-$(CONFIG_SOUND_PXA_AUDIO) += pxa-audio.o
+ obj-$(CONFIG_SOUND_YMFPCI) += ymfpci.o ac97_codec.o
+ ifeq ($(CONFIG_SOUND_YMFPCI_LEGACY),y)
+ obj-$(CONFIG_SOUND_YMFPCI) += opl3.o uart401.o
+Index: linux-2.6.15gum/sound/oss/ac97_codec.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/ac97_codec.c
++++ linux-2.6.15gum/sound/oss/ac97_codec.c
+@@ -84,6 +84,7 @@ static int crystal_digital_control(struc
+ static int cmedia_init(struct ac97_codec * codec);
+ static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
+ static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
++static int ucb1400_init(struct ac97_codec *codec);
+
+
+ /*
+@@ -119,6 +120,7 @@ static struct ac97_ops crystal_digital_o
+ static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
+ static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL};
+ static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control};
++static struct ac97_ops ucb1400_ops = { ucb1400_init, eapd_control, NULL };
+
+ /* sorted by vendor/device id */
+ static const struct {
+@@ -164,6 +166,7 @@ static const struct {
+ {0x4e534331, "National Semiconductor LM4549", &null_ops},
+ {0x53494c22, "Silicon Laboratory Si3036", &null_ops},
+ {0x53494c23, "Silicon Laboratory Si3038", &null_ops},
++ {0x50534304, "Philips UCB1400", &ucb1400_ops},
+ {0x545200FF, "TriTech TR?????", &tritech_m_ops},
+ {0x54524102, "TriTech TR28022", &null_ops},
+ {0x54524103, "TriTech TR28023", &null_ops},
+@@ -461,6 +464,17 @@ static void ac97_write_mixer(struct ac97
+ val = codec->codec_read(codec, mh->offset);
+ printk(" -> 0x%04x\n", val);
+ #endif
++
++ if (val & AC97_MUTE)
++ val = 0;
++ else
++ val = 1;
++ if ((oss_channel == SOUND_MIXER_VOLUME) &&
++ (codec->codec_ops->amplifier) &&
++ (codec->power != val)) {
++ codec->power = val;
++ codec->codec_ops->amplifier (codec, codec->power);
++ }
+ }
+
+ /* a thin wrapper for write_mixer */
+@@ -1092,6 +1106,13 @@ static int wolfson_init05(struct ac97_co
+ {
+ /* set front mixer volume */
+ codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
++ /*codec->codec_write(codec, 0x78, 0xc004);
++ while(1){
++ codec->codec_write(codec, 0x76, 0xa020);
++ printk("%08x ", codec->codec_read(codec, 0x76));
++ printk("%08x ", codec->codec_read(codec, 0x78));
++ printk("%08x\n", codec->codec_read(codec, 0x7A));
++ }*/
+ return 0;
+ }
+
+@@ -1313,6 +1334,14 @@ static int pt101_init(struct ac97_codec
+ }
+ #endif
+
++static int ucb1400_init(struct ac97_codec *codec)
++{
++ codec->codec_write(codec,AC97_EXTENDED_STATUS,1);
++ //codec->codec_write(codec, 0x6a, 0x1ff7);
++ codec->codec_write(codec, 0x6a, 0x0050);
++ codec->codec_write(codec, 0x6c, 0x0030);
++ return 0;
++}
+
+ EXPORT_SYMBOL(ac97_read_proc);
+ EXPORT_SYMBOL(ac97_probe_codec);
+Index: linux-2.6.15gum/sound/oss/pxa-ac97.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/sound/oss/pxa-ac97.c
+@@ -0,0 +1,357 @@
++/*
++ * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip
++ *
++ * Author: Nicolas Pitre
++ * Created: Aug 15, 2001
++ * Copyright: MontaVista Software Inc.
++ *
++ * Forward ported to 2.6 by Ian Molton 15/09/2003
++ *
++ * 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/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/pci.h>
++#include <linux/interrupt.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/poll.h>
++#include <linux/sound.h>
++#include <linux/soundcard.h>
++#include <linux/ac97_codec.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++#include <asm/dma.h>
++
++#include "pxa-audio.h"
++
++static struct completion CAR_completion;
++static int waitingForMask;
++static DECLARE_MUTEX(CAR_mutex);
++
++static u16 pxa_ac97_read(struct ac97_codec *codec, u8 reg)
++{
++ u16 val = -1;
++
++ down(&CAR_mutex);
++ if (!(CAR & CAR_CAIP)) {
++ volatile u32 *reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1);
++
++ waitingForMask=GSR_SDONE;
++
++ init_completion(&CAR_completion);
++ (void)*reg_addr; //start read access across the ac97 link
++ wait_for_completion(&CAR_completion);
++
++ if (GSR & GSR_RDCS) {
++ GSR = GSR_RDCS; //write a 1 to clear
++ printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__);
++ }
++
++ init_completion(&CAR_completion);
++ val = *reg_addr; //valid data now but we've just started another cycle...
++ wait_for_completion(&CAR_completion);
++
++ } else {
++ printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__);
++ }
++ up(&CAR_mutex);
++ //printk("%s(0x%02x) = 0x%04x\n", __FUNCTION__, reg, val);
++ return val;
++}
++
++static void pxa_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
++{
++ down(&CAR_mutex);
++ if (!(CAR & CAR_CAIP)) {
++ volatile u32 *reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1);
++
++ waitingForMask=GSR_CDONE;
++ init_completion(&CAR_completion);
++ *reg_addr = val;
++ wait_for_completion(&CAR_completion);
++ } else {
++ printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__);
++ }
++ up(&CAR_mutex);
++ //printk("%s(0x%02x, 0x%04x)\n", __FUNCTION__, reg, val);
++}
++
++static irqreturn_t pxa_ac97_irq(int irq, void *dev_id, struct pt_regs *regs)
++{
++ int gsr = GSR;
++ GSR = gsr & (GSR_SDONE|GSR_CDONE); //write a 1 to clear
++ if (gsr & waitingForMask)
++ complete(&CAR_completion);
++
++ return IRQ_HANDLED;
++}
++
++static struct ac97_codec pxa_ac97_codec = {
++ codec_read: pxa_ac97_read,
++ codec_write: pxa_ac97_write,
++};
++
++static DECLARE_MUTEX(pxa_ac97_mutex);
++static int pxa_ac97_refcount;
++
++int pxa_ac97_get(struct ac97_codec **codec)
++{
++ int ret;
++
++ *codec = NULL;
++ down(&pxa_ac97_mutex);
++
++ if (!pxa_ac97_refcount) {
++ ret = request_irq(IRQ_AC97, pxa_ac97_irq, 0, "AC97", NULL);
++ if (ret)
++ return ret;
++
++ CKEN |= CKEN2_AC97;
++
++ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
++ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
++ pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
++ pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
++
++ GCR = 0;
++ udelay(10);
++ GCR = GCR_COLD_RST|GCR_CDONE_IE|GCR_SDONE_IE;
++ while (!(GSR & GSR_PCR)) {
++ schedule();
++ }
++
++ ret = ac97_probe_codec(&pxa_ac97_codec);
++ if (ret != 1) {
++ free_irq(IRQ_AC97, NULL);
++ GCR = GCR_ACLINK_OFF;
++ CKEN &= ~CKEN2_AC97;
++ return ret;
++ }
++ }
++
++ pxa_ac97_refcount++;
++ up(&pxa_ac97_mutex);
++ *codec = &pxa_ac97_codec;
++ return 0;
++}
++
++void pxa_ac97_put(void)
++{
++ down(&pxa_ac97_mutex);
++ pxa_ac97_refcount--;
++ if (!pxa_ac97_refcount) {
++ GCR = GCR_ACLINK_OFF;
++ CKEN &= ~CKEN2_AC97;
++ free_irq(IRQ_AC97, NULL);
++ }
++ up(&pxa_ac97_mutex);
++}
++
++EXPORT_SYMBOL(pxa_ac97_get);
++EXPORT_SYMBOL(pxa_ac97_put);
++
++
++/*
++ * Audio Mixer stuff
++ */
++
++static audio_state_t ac97_audio_state;
++static audio_stream_t ac97_audio_in;
++
++/*
++ * According to the PXA250 spec, mic-in should use different
++ * DRCMR and different AC97 FIFO.
++ * Unfortunately current UCB1400 versions (up to ver 2A) don't
++ * produce slot 6 for the audio input frame, therefore the PXA
++ * AC97 mic-in FIFO is always starved.
++ * But since UCB1400 is not the only audio CODEC out there,
++ * this is still enabled by default.
++ */
++static void update_audio_in (void)
++{
++#if 1
++ long val;
++
++ /* Use the value stuffed by ac97_recmask_io()
++ * into recording select register
++ */
++ val = pxa_ac97_codec.codec_read(&pxa_ac97_codec, AC97_RECORD_SELECT);
++ pxa_audio_clear_buf(&ac97_audio_in);
++ *ac97_audio_in.drcmr = 0;
++ if (val == 0) {
++ ac97_audio_in.dcmd = DCMD_RXMCDR;
++ ac97_audio_in.drcmr = &DRCMRRXMCDR;
++ ac97_audio_in.dev_addr = __PREG(MCDR);
++ } else {
++ ac97_audio_in.dcmd = DCMD_RXPCDR;
++ ac97_audio_in.drcmr = &DRCMRRXPCDR;
++ ac97_audio_in.dev_addr = __PREG(PCDR);
++ }
++ if (ac97_audio_state.rd_ref)
++ *ac97_audio_in.drcmr =
++ ac97_audio_in.dma_ch | DRCMR_MAPVLD;
++#endif
++}
++
++static int mixer_ioctl( struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++ int ret;
++
++ ret = pxa_ac97_codec.mixer_ioctl(&pxa_ac97_codec, cmd, arg);
++ if (ret)
++ return ret;
++
++ /* We must snoop for some commands to provide our own extra processing */
++ switch (cmd) {
++ case SOUND_MIXER_WRITE_RECSRC:
++ update_audio_in ();
++ break;
++ }
++ return 0;
++}
++
++static struct file_operations mixer_fops = {
++ ioctl: mixer_ioctl,
++ llseek: no_llseek,
++ owner: THIS_MODULE
++};
++
++/*
++ * AC97 codec ioctls
++ */
++
++static int codec_adc_rate = 48000;
++static int codec_dac_rate = 48000;
++
++static int ac97_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++ int ret;
++ long val = 0;
++
++ switch(cmd) {
++ case SNDCTL_DSP_STEREO:
++ ret = get_user(val, (int *) arg);
++ if (ret)
++ return ret;
++ /* FIXME: do we support mono? */
++ ret = (val == 0) ? -EINVAL : 1;
++ return put_user(ret, (int *) arg);
++
++ case SNDCTL_DSP_CHANNELS:
++ case SOUND_PCM_READ_CHANNELS:
++ /* FIXME: do we support mono? */
++ return put_user(2, (long *) arg);
++
++ case SNDCTL_DSP_SPEED:
++ ret = get_user(val, (long *) arg);
++ if (ret)
++ return ret;
++ if (file->f_mode & FMODE_READ)
++ codec_adc_rate = ac97_set_adc_rate(&pxa_ac97_codec, val);
++ if (file->f_mode & FMODE_WRITE)
++ codec_dac_rate = ac97_set_dac_rate(&pxa_ac97_codec, val);
++ /* fall through */
++ case SOUND_PCM_READ_RATE:
++ if (file->f_mode & FMODE_READ)
++ val = codec_adc_rate;
++ if (file->f_mode & FMODE_WRITE)
++ val = codec_dac_rate;
++ return put_user(val, (long *) arg);
++
++ case SNDCTL_DSP_SETFMT:
++ case SNDCTL_DSP_GETFMTS:
++ /* FIXME: can we do other fmts? */
++ return put_user(AFMT_S16_LE, (long *) arg);
++
++ default:
++ /* Maybe this is meant for the mixer (As per OSS Docs) */
++ return mixer_ioctl(inode, file, cmd, arg);
++ }
++ return 0;
++}
++
++
++/*
++ * Audio stuff
++ */
++
++static audio_stream_t ac97_audio_out = {
++ name: "AC97 audio out",
++ dcmd: DCMD_TXPCDR,
++ drcmr: &DRCMRTXPCDR,
++ dev_addr: __PREG(PCDR),
++};
++
++static audio_stream_t ac97_audio_in = {
++ name: "AC97 audio in",
++ dcmd: DCMD_RXPCDR,
++ drcmr: &DRCMRRXPCDR,
++ dev_addr: __PREG(PCDR),
++};
++
++static audio_state_t ac97_audio_state = {
++ output_stream: &ac97_audio_out,
++ input_stream: &ac97_audio_in,
++ client_ioctl: ac97_ioctl,
++ sem: __MUTEX_INITIALIZER(ac97_audio_state.sem),
++};
++
++static int ac97_audio_open(struct inode *inode, struct file *file)
++{
++ return pxa_audio_attach(inode, file, &ac97_audio_state);
++}
++
++/*
++ * Missing fields of this structure will be patched with the call
++ * to pxa_audio_attach().
++ */
++
++static struct file_operations ac97_audio_fops = {
++ open: ac97_audio_open,
++ owner: THIS_MODULE
++};
++
++
++static int __init pxa_ac97_init(void)
++{
++ int ret;
++ struct ac97_codec *dummy;
++
++ ret = pxa_ac97_get(&dummy);
++ if (ret)
++ return ret;
++
++ update_audio_in ();
++
++ ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1);
++ pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1);
++
++ return 0;
++}
++
++static void __exit pxa_ac97_exit(void)
++{
++ unregister_sound_dsp(ac97_audio_state.dev_dsp);
++ unregister_sound_mixer(pxa_ac97_codec.dev_mixer);
++ pxa_ac97_put();
++}
++
++
++module_init(pxa_ac97_init);
++module_exit(pxa_ac97_exit);
++
++MODULE_AUTHOR("Nicolas Pitre");
++MODULE_DESCRIPTION("AC97 interface for the Cotula chip");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.15gum/sound/oss/pxa-audio.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/sound/oss/pxa-audio.c
+@@ -0,0 +1,858 @@
++/*
++ * linux/drivers/sound/pxa-audio.c -- audio interface for the Cotula chip
++ *
++ * Author: Nicolas Pitre
++ * Created: Aug 15, 2001
++ * Copyright: MontaVista Software Inc.
++ *
++ * 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/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/pci.h>
++#include <linux/poll.h>
++#include <linux/sound.h>
++#include <linux/soundcard.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++#include <asm/dma.h>
++
++#include "pxa-audio.h"
++
++
++#define AUDIO_NBFRAGS_DEFAULT 8
++#define AUDIO_FRAGSIZE_DEFAULT 8192
++
++#define MAX_DMA_SIZE 4096
++#define DMA_DESC_SIZE sizeof(pxa_dma_desc)
++
++
++/*
++ * This function frees all buffers
++ */
++#define audio_clear_buf pxa_audio_clear_buf
++
++void pxa_audio_clear_buf(audio_stream_t * s)
++{
++ DECLARE_WAITQUEUE(wait, current);
++ int frag;
++
++ if (!s->buffers)
++ return;
++
++ /* Ensure DMA isn't running */
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ add_wait_queue(&s->stop_wq, &wait);
++ DCSR(s->dma_ch) = DCSR_STOPIRQEN;
++ schedule();
++ remove_wait_queue(&s->stop_wq, &wait);
++
++ /* free DMA buffers */
++ for (frag = 0; frag < s->nbfrags; frag++) {
++ audio_buf_t *b = &s->buffers[frag];
++ if (!b->master)
++ continue;
++ dma_free_writecombine(NULL, b->master, b->data, b->dma_desc->dsadr);
++ }
++
++ /* free descriptor ring */
++ if (s->buffers->dma_desc)
++ dma_free_writecombine(NULL, s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE,
++ s->buffers->dma_desc, s->dma_desc_phys);
++
++ /* free buffer structure array */
++ kfree(s->buffers);
++ s->buffers = NULL;
++}
++
++/*
++ * This function allocates the DMA descriptor array and buffer data space
++ * according to the current number of fragments and fragment size.
++ */
++static int audio_setup_buf(audio_stream_t * s)
++{
++ pxa_dma_desc *dma_desc;
++ dma_addr_t dma_desc_phys;
++ int nb_desc, frag, i, buf_size = 0;
++ char *dma_buf = NULL;
++ dma_addr_t dma_buf_phys = 0;
++
++ if (s->buffers)
++ return -EBUSY;
++
++ /* Our buffer structure array */
++ s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
++ if (!s->buffers)
++ goto err;
++ memzero(s->buffers, sizeof(audio_buf_t) * s->nbfrags);
++
++ /*
++ * Our DMA descriptor array:
++ * for Each fragment we have one checkpoint descriptor plus one
++ * descriptor per MAX_DMA_SIZE byte data blocks.
++ */
++ nb_desc = (1 + (s->fragsize + MAX_DMA_SIZE - 1)/MAX_DMA_SIZE) * s->nbfrags;
++ dma_desc = dma_alloc_writecombine(NULL, nb_desc * DMA_DESC_SIZE,
++ &dma_desc_phys, GFP_KERNEL);
++
++ if (!dma_desc)
++ goto err;
++ s->descs_per_frag = nb_desc / s->nbfrags;
++ s->buffers->dma_desc = dma_desc;
++ s->dma_desc_phys = dma_desc_phys;
++ for (i = 0; i < nb_desc - 1; i++)
++ dma_desc[i].ddadr = dma_desc_phys + (i + 1) * DMA_DESC_SIZE;
++ dma_desc[i].ddadr = dma_desc_phys;
++
++ /* Our actual DMA buffers */
++ for (frag = 0; frag < s->nbfrags; frag++) {
++ audio_buf_t *b = &s->buffers[frag];
++
++ /*
++ * Let's allocate non-cached memory for DMA buffers.
++ * We try to allocate all memory at once.
++ * If this fails (a common reason is memory fragmentation),
++ * then we'll try allocating smaller buffers.
++ */
++ if (!buf_size) {
++ buf_size = (s->nbfrags - frag) * s->fragsize;
++ do {
++ dma_buf = dma_alloc_writecombine(NULL, buf_size,
++ &dma_buf_phys,
++ GFP_KERNEL);
++ if (!dma_buf)
++ buf_size -= s->fragsize;
++ } while (!dma_buf && buf_size);
++ if (!dma_buf)
++ goto err;
++ b->master = buf_size;
++ memzero(dma_buf, buf_size);
++ }
++
++ /*
++ * Set up our checkpoint descriptor. Since the count
++ * is always zero, we'll abuse the dsadr and dtadr fields
++ * just in case this one is picked up by the hardware
++ * while processing SOUND_DSP_GETPTR.
++ */
++ dma_desc->dsadr = dma_buf_phys;
++ dma_desc->dtadr = dma_buf_phys;
++ dma_desc->dcmd = DCMD_ENDIRQEN;
++ if (s->output && !s->mapped)
++ dma_desc->ddadr |= DDADR_STOP;
++ b->dma_desc = dma_desc++;
++
++ /* set up the actual data descriptors */
++ for (i = 0; (i * MAX_DMA_SIZE) < s->fragsize; i++) {
++ dma_desc[i].dsadr = (s->output) ?
++ (dma_buf_phys + i*MAX_DMA_SIZE) : s->dev_addr;
++ dma_desc[i].dtadr = (s->output) ?
++ s->dev_addr : (dma_buf_phys + i*MAX_DMA_SIZE);
++ dma_desc[i].dcmd = s->dcmd |
++ ((s->fragsize < MAX_DMA_SIZE) ?
++ s->fragsize : MAX_DMA_SIZE);
++ }
++ dma_desc += i;
++
++ /* handle buffer pointers */
++ b->data = dma_buf;
++ dma_buf += s->fragsize;
++ dma_buf_phys += s->fragsize;
++ buf_size -= s->fragsize;
++ }
++
++ s->usr_frag = s->dma_frag = 0;
++ s->bytecount = 0;
++ s->fragcount = 0;
++ sema_init(&s->sem, (s->output) ? s->nbfrags : 0);
++ return 0;
++
++err:
++ printk("pxa-audio: unable to allocate audio memory\n ");
++ audio_clear_buf(s);
++ return -ENOMEM;
++}
++
++/*
++ * Our DMA interrupt handler
++ */
++static void audio_dma_irq(int ch, void *dev_id, struct pt_regs *regs)
++{
++ audio_stream_t *s = dev_id;
++ u_int dcsr;
++
++ dcsr = DCSR(ch);
++ DCSR(ch) = dcsr & ~DCSR_STOPIRQEN;
++
++ if (!s->buffers) {
++ printk("AC97 DMA: wow... received IRQ for channel %d but no buffer exists\n", ch);
++ return;
++ }
++
++ if (dcsr & DCSR_BUSERR)
++ printk("AC97 DMA: bus error interrupt on channel %d\n", ch);
++
++ if (dcsr & DCSR_ENDINTR) {
++ u_long cur_dma_desc;
++ u_int cur_dma_frag;
++
++ /*
++ * Find out which DMA desc is current. Note that DDADR
++ * points to the next desc, not the current one.
++ */
++ cur_dma_desc = DDADR(ch) - s->dma_desc_phys - DMA_DESC_SIZE;
++
++ /*
++ * Let the compiler nicely optimize constant divisors into
++ * multiplications for the common cases which is much faster.
++ * Common cases: x = 1 + (1 << y) for y = [0..3]
++ */
++ switch (s->descs_per_frag) {
++ case 2: cur_dma_frag = cur_dma_desc / (2*DMA_DESC_SIZE); break;
++ case 3: cur_dma_frag = cur_dma_desc / (3*DMA_DESC_SIZE); break;
++ case 5: cur_dma_frag = cur_dma_desc / (5*DMA_DESC_SIZE); break;
++ case 9: cur_dma_frag = cur_dma_desc / (9*DMA_DESC_SIZE); break;
++ default: cur_dma_frag =
++ cur_dma_desc / (s->descs_per_frag * DMA_DESC_SIZE);
++ }
++
++ /* Account for possible wrap back of cur_dma_desc above */
++ if (cur_dma_frag >= s->nbfrags)
++ cur_dma_frag = s->nbfrags - 1;
++
++ while (s->dma_frag != cur_dma_frag) {
++ if (!s->mapped) {
++ /*
++ * This fragment is done - set the checkpoint
++ * descriptor to STOP until it is gets
++ * processed by the read or write function.
++ */
++ s->buffers[s->dma_frag].dma_desc->ddadr |= DDADR_STOP;
++ up(&s->sem);
++ }
++ if (++s->dma_frag >= s->nbfrags)
++ s->dma_frag = 0;
++
++ /* Accounting */
++ s->bytecount += s->fragsize;
++ s->fragcount++;
++ }
++
++ /* ... and for polling processes */
++ wake_up(&s->frag_wq);
++ }
++
++ if ((dcsr & DCSR_STOPIRQEN) && (dcsr & DCSR_STOPSTATE))
++ wake_up(&s->stop_wq);
++}
++
++/*
++ * Validate and sets up buffer fragments, etc.
++ */
++static int audio_set_fragments(audio_stream_t *s, int val)
++{
++ if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN)
++ return -EBUSY;
++ if (s->buffers)
++ audio_clear_buf(s);
++ s->nbfrags = (val >> 16) & 0x7FFF;
++ val &= 0xffff;
++ if (val < 5)
++ val = 5;
++ if (val > 15)
++ val = 15;
++ s->fragsize = 1 << val;
++ if (s->nbfrags < 2)
++ s->nbfrags = 2;
++ if (s->nbfrags * s->fragsize > 256 * 1024)
++ s->nbfrags = 256 * 1024 / s->fragsize;
++ if (audio_setup_buf(s))
++ return -ENOMEM;
++ return val|(s->nbfrags << 16);
++}
++
++
++/*
++ * The fops functions
++ */
++
++static int audio_write(struct file *file, const char *buffer,
++ size_t count, loff_t * ppos)
++{
++ const char *buffer0 = buffer;
++ audio_state_t *state = (audio_state_t *)file->private_data;
++ audio_stream_t *s = state->output_stream;
++ int chunksize, ret = 0;
++
++ if (ppos != &file->f_pos)
++ return -ESPIPE;
++ if (s->mapped)
++ return -ENXIO;
++ if (!s->buffers && audio_setup_buf(s))
++ return -ENOMEM;
++
++ while (count > 0) {
++ audio_buf_t *b = &s->buffers[s->usr_frag];
++
++ /* Grab a fragment */
++ if (file->f_flags & O_NONBLOCK) {
++ ret = -EAGAIN;
++ if (down_trylock(&s->sem))
++ break;
++ } else {
++ ret = -ERESTARTSYS;
++ if (down_interruptible(&s->sem))
++ break;
++ }
++
++ /* Feed the current buffer */
++ chunksize = s->fragsize - b->offset;
++ if (chunksize > count)
++ chunksize = count;
++ if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
++ up(&s->sem);
++ return -EFAULT;
++ }
++
++ b->offset += chunksize;
++ buffer += chunksize;
++ count -= chunksize;
++ if (b->offset < s->fragsize) {
++ ret = 0;
++ up(&s->sem);
++ break;
++ }
++
++ /*
++ * Activate DMA on current buffer.
++ * We unlock this fragment's checkpoint descriptor and
++ * kick DMA if it is idle. Using checkpoint descriptors
++ * allows for control operations without the need for
++ * stopping the DMA channel if it is already running.
++ */
++ b->offset = 0;
++ b->dma_desc->ddadr &= ~DDADR_STOP;
++ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
++ DDADR(s->dma_ch) = b->dma_desc->ddadr;
++ DCSR(s->dma_ch) = DCSR_RUN;
++ }
++
++ /* move the index to the next fragment */
++ if (++s->usr_frag >= s->nbfrags)
++ s->usr_frag = 0;
++ }
++
++ if ((buffer - buffer0))
++ ret = buffer - buffer0;
++ return ret;
++}
++
++
++static int audio_read(struct file *file, char *buffer,
++ size_t count, loff_t * ppos)
++{
++ char *buffer0 = buffer;
++ audio_state_t *state = file->private_data;
++ audio_stream_t *s = state->input_stream;
++ int chunksize, ret = 0;
++
++ if (ppos != &file->f_pos)
++ return -ESPIPE;
++ if (s->mapped)
++ return -ENXIO;
++ if (!s->buffers && audio_setup_buf(s))
++ return -ENOMEM;
++
++ while (count > 0) {
++ audio_buf_t *b = &s->buffers[s->usr_frag];
++
++ /* prime DMA */
++ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
++ DDADR(s->dma_ch) =
++ s->buffers[s->dma_frag].dma_desc->ddadr;
++ DCSR(s->dma_ch) = DCSR_RUN;
++ }
++
++ /* Wait for a buffer to become full */
++ if (file->f_flags & O_NONBLOCK) {
++ ret = -EAGAIN;
++ if (down_trylock(&s->sem))
++ break;
++ } else {
++ ret = -ERESTARTSYS;
++ if (down_interruptible(&s->sem))
++ break;
++ }
++
++ /* Grab data from current buffer */
++ chunksize = s->fragsize - b->offset;
++ if (chunksize > count)
++ chunksize = count;
++ if (copy_to_user(buffer, b->data + b->offset, chunksize)) {
++ up(&s->sem);
++ return -EFAULT;
++ }
++ b->offset += chunksize;
++ buffer += chunksize;
++ count -= chunksize;
++ if (b->offset < s->fragsize) {
++ ret = 0;
++ up(&s->sem);
++ break;
++ }
++
++ /*
++ * Make this buffer available for DMA again.
++ * We unlock this fragment's checkpoint descriptor and
++ * kick DMA if it is idle. Using checkpoint descriptors
++ * allows for control operations without the need for
++ * stopping the DMA channel if it is already running.
++ */
++ b->offset = 0;
++ b->dma_desc->ddadr &= ~DDADR_STOP;
++
++ /* move the index to the next fragment */
++ if (++s->usr_frag >= s->nbfrags)
++ s->usr_frag = 0;
++ }
++
++ if ((buffer - buffer0))
++ ret = buffer - buffer0;
++ return ret;
++}
++
++
++static int audio_sync(struct file *file)
++{
++ audio_state_t *state = file->private_data;
++ audio_stream_t *s = state->output_stream;
++ audio_buf_t *b;
++ pxa_dma_desc *final_desc;
++ u_long dcmd_save = 0;
++ DECLARE_WAITQUEUE(wait, current);
++
++ if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped)
++ return 0;
++
++ /*
++ * Send current buffer if it contains data. Be sure to send
++ * a full sample count.
++ */
++ final_desc = NULL;
++ b = &s->buffers[s->usr_frag];
++ if (b->offset &= ~3) {
++ final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE];
++ b->offset &= (MAX_DMA_SIZE-1);
++ dcmd_save = final_desc->dcmd;
++ final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN;
++ final_desc->ddadr |= DDADR_STOP;
++ b->offset = 0;
++ b->dma_desc->ddadr &= ~DDADR_STOP;
++ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
++ DDADR(s->dma_ch) = b->dma_desc->ddadr;
++ DCSR(s->dma_ch) = DCSR_RUN;
++ }
++ }
++
++ /* Wait for DMA to complete. */
++ set_current_state(TASK_INTERRUPTIBLE);
++#if 0
++ /*
++ * The STOPSTATE IRQ never seem to occur if DCSR_STOPIRQEN is set
++ * along wotj DCSR_RUN. Silicon bug?
++ */
++ add_wait_queue(&s->stop_wq, &wait);
++ DCSR(s->dma_ch) |= DCSR_STOPIRQEN;
++ schedule();
++#else
++ add_wait_queue(&s->frag_wq, &wait);
++ while ((DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current)) {
++ schedule();
++ set_current_state(TASK_INTERRUPTIBLE);
++ }
++#endif
++ set_current_state(TASK_RUNNING);
++ remove_wait_queue(&s->frag_wq, &wait);
++
++ /* Restore the descriptor chain. */
++ if (final_desc) {
++ final_desc->dcmd = dcmd_save;
++ final_desc->ddadr &= ~DDADR_STOP;
++ b->dma_desc->ddadr |= DDADR_STOP;
++ }
++ return 0;
++}
++
++
++static unsigned int audio_poll(struct file *file,
++ struct poll_table_struct *wait)
++{
++ audio_state_t *state = file->private_data;
++ audio_stream_t *is = state->input_stream;
++ audio_stream_t *os = state->output_stream;
++ unsigned int mask = 0;
++
++ if (file->f_mode & FMODE_READ) {
++ /* Start audio input if not already active */
++ if (!is->buffers && audio_setup_buf(is))
++ return -ENOMEM;
++ if (DCSR(is->dma_ch) & DCSR_STOPSTATE) {
++ DDADR(is->dma_ch) =
++ is->buffers[is->dma_frag].dma_desc->ddadr;
++ DCSR(is->dma_ch) = DCSR_RUN;
++ }
++ poll_wait(file, &is->frag_wq, wait);
++ }
++
++ if (file->f_mode & FMODE_WRITE) {
++ if (!os->buffers && audio_setup_buf(os))
++ return -ENOMEM;
++ poll_wait(file, &os->frag_wq, wait);
++ }
++
++ if (file->f_mode & FMODE_READ)
++ if (( is->mapped && is->bytecount > 0) ||
++ (!is->mapped && atomic_read(&is->sem.count) > 0))
++ mask |= POLLIN | POLLRDNORM;
++
++ if (file->f_mode & FMODE_WRITE)
++ if (( os->mapped && os->bytecount > 0) ||
++ (!os->mapped && atomic_read(&os->sem.count) > 0))
++ mask |= POLLOUT | POLLWRNORM;
++
++ return mask;
++}
++
++
++static int audio_ioctl( struct inode *inode, struct file *file,
++ uint cmd, ulong arg)
++{
++ audio_state_t *state = file->private_data;
++ audio_stream_t *os = state->output_stream;
++ audio_stream_t *is = state->input_stream;
++ long val;
++
++ switch (cmd) {
++ case OSS_GETVERSION:
++ return put_user(SOUND_VERSION, (int *)arg);
++
++ case SNDCTL_DSP_GETBLKSIZE:
++ if (file->f_mode & FMODE_WRITE)
++ return put_user(os->fragsize, (int *)arg);
++ else
++ return put_user(is->fragsize, (int *)arg);
++
++ case SNDCTL_DSP_GETCAPS:
++ val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP;
++ if (is && os)
++ val |= DSP_CAP_DUPLEX;
++ return put_user(val, (int *)arg);
++
++ case SNDCTL_DSP_SETFRAGMENT:
++ if (get_user(val, (long *) arg))
++ return -EFAULT;
++ if (file->f_mode & FMODE_READ) {
++ int ret = audio_set_fragments(is, val);
++ if (ret < 0)
++ return ret;
++ ret = put_user(ret, (int *)arg);
++ if (ret)
++ return ret;
++ }
++ if (file->f_mode & FMODE_WRITE) {
++ int ret = audio_set_fragments(os, val);
++ if (ret < 0)
++ return ret;
++ ret = put_user(ret, (int *)arg);
++ if (ret)
++ return ret;
++ }
++ return 0;
++
++ case SNDCTL_DSP_SYNC:
++ return audio_sync(file);
++
++ case SNDCTL_DSP_SETDUPLEX:
++ return 0;
++
++ case SNDCTL_DSP_POST:
++ return 0;
++
++ case SNDCTL_DSP_GETTRIGGER:
++ val = 0;
++ if (file->f_mode & FMODE_READ && DCSR(is->dma_ch) & DCSR_RUN)
++ val |= PCM_ENABLE_INPUT;
++ if (file->f_mode & FMODE_WRITE && DCSR(os->dma_ch) & DCSR_RUN)
++ val |= PCM_ENABLE_OUTPUT;
++ return put_user(val, (int *)arg);
++
++ case SNDCTL_DSP_SETTRIGGER:
++ if (get_user(val, (int *)arg))
++ return -EFAULT;
++ if (file->f_mode & FMODE_READ) {
++ if (val & PCM_ENABLE_INPUT) {
++ if (!is->buffers && audio_setup_buf(is))
++ return -ENOMEM;
++ if (!(DCSR(is->dma_ch) & DCSR_RUN)) {
++ audio_buf_t *b = &is->buffers[is->dma_frag];
++ DDADR(is->dma_ch) = b->dma_desc->ddadr;
++ DCSR(is->dma_ch) = DCSR_RUN;
++ }
++ } else {
++ DCSR(is->dma_ch) = 0;
++ }
++ }
++ if (file->f_mode & FMODE_WRITE) {
++ if (val & PCM_ENABLE_OUTPUT) {
++ if (!os->buffers && audio_setup_buf(os))
++ return -ENOMEM;
++ if (!(DCSR(os->dma_ch) & DCSR_RUN)) {
++ audio_buf_t *b = &os->buffers[os->dma_frag];
++ DDADR(os->dma_ch) = b->dma_desc->ddadr;
++ DCSR(os->dma_ch) = DCSR_RUN;
++ }
++ } else {
++ DCSR(os->dma_ch) = 0;
++ }
++ }
++ return 0;
++
++ case SNDCTL_DSP_GETOSPACE:
++ case SNDCTL_DSP_GETISPACE:
++ {
++ audio_buf_info inf = { 0, };
++ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOSPACE) ? os : is;
++
++ if ((s == is && !(file->f_mode & FMODE_READ)) ||
++ (s == os && !(file->f_mode & FMODE_WRITE)))
++ return -EINVAL;
++ if (!s->buffers && audio_setup_buf(s))
++ return -ENOMEM;
++ inf.bytes = atomic_read(&s->sem.count) * s->fragsize;
++ inf.bytes -= s->buffers[s->usr_frag].offset;
++ inf.fragments = inf.bytes / s->fragsize;
++ inf.fragsize = s->fragsize;
++ inf.fragstotal = s->nbfrags;
++ return copy_to_user((void *)arg, &inf, sizeof(inf));
++ }
++
++ case SNDCTL_DSP_GETOPTR:
++ case SNDCTL_DSP_GETIPTR:
++ {
++ count_info inf = { 0, };
++ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
++ dma_addr_t ptr;
++ int bytecount, offset;
++ unsigned long flags;
++
++ if ((s == is && !(file->f_mode & FMODE_READ)) ||
++ (s == os && !(file->f_mode & FMODE_WRITE)))
++ return -EINVAL;
++ local_irq_save(flags);
++ if (DCSR(s->dma_ch) & DCSR_RUN) {
++ audio_buf_t *b;
++ ptr = (s->output) ? DSADR(s->dma_ch) : DTADR(s->dma_ch);
++ b = &s->buffers[s->dma_frag];
++ offset = ptr - b->dma_desc->dsadr;
++ if (offset >= s->fragsize)
++ offset = s->fragsize - 4;
++ } else {
++ offset = 0;
++ }
++ inf.ptr = s->dma_frag * s->fragsize + offset;
++ bytecount = s->bytecount + offset;
++ s->bytecount = -offset;
++ inf.blocks = s->fragcount;
++ s->fragcount = 0;
++ local_irq_restore(flags);
++ if (bytecount < 0)
++ bytecount = 0;
++ inf.bytes = bytecount;
++ return copy_to_user((void *)arg, &inf, sizeof(inf));
++ }
++
++ case SNDCTL_DSP_NONBLOCK:
++ file->f_flags |= O_NONBLOCK;
++ return 0;
++
++ case SNDCTL_DSP_RESET:
++ if (file->f_mode & FMODE_WRITE)
++ audio_clear_buf(os);
++ if (file->f_mode & FMODE_READ)
++ audio_clear_buf(is);
++ return 0;
++
++ default:
++ return state->client_ioctl ?
++ state->client_ioctl(inode, file, cmd, arg) : -EINVAL;
++ }
++
++ return 0;
++}
++
++
++static int audio_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ audio_state_t *state = file->private_data;
++ audio_stream_t *s;
++ unsigned long size, vma_addr;
++ int i, ret;
++
++ if (vma->vm_pgoff != 0)
++ return -EINVAL;
++
++ if (vma->vm_flags & VM_WRITE) {
++ if (!state->wr_ref)
++ return -EINVAL;;
++ s = state->output_stream;
++ } else if (vma->vm_flags & VM_READ) {
++ if (!state->rd_ref)
++ return -EINVAL;
++ s = state->input_stream;
++ } else return -EINVAL;
++
++ if (s->mapped)
++ return -EINVAL;
++ size = vma->vm_end - vma->vm_start;
++ if (size != s->fragsize * s->nbfrags)
++ return -EINVAL;
++ if (!s->buffers && audio_setup_buf(s))
++ return -ENOMEM;
++ vma_addr = vma->vm_start;
++ for (i = 0; i < s->nbfrags; i++) {
++ audio_buf_t *buf = &s->buffers[i];
++ if (!buf->master)
++ continue;
++ ret = remap_page_range(vma, vma->vm_start, buf->dma_desc->dsadr,
++ buf->master, vma->vm_page_prot);
++ if (ret)
++ return ret;
++ vma_addr += buf->master;
++ }
++ for (i = 0; i < s->nbfrags; i++)
++ s->buffers[i].dma_desc->ddadr &= ~DDADR_STOP;
++ s->mapped = 1;
++ return 0;
++}
++
++
++static int audio_release(struct inode *inode, struct file *file)
++{
++ audio_state_t *state = file->private_data;
++
++ down(&state->sem);
++
++ if (file->f_mode & FMODE_READ) {
++ audio_clear_buf(state->input_stream);
++ *state->input_stream->drcmr = 0;
++ pxa_free_dma(state->input_stream->dma_ch);
++ state->rd_ref = 0;
++ }
++
++ if (file->f_mode & FMODE_WRITE) {
++ audio_sync(file);
++ audio_clear_buf(state->output_stream);
++ *state->output_stream->drcmr = 0;
++ pxa_free_dma(state->output_stream->dma_ch);
++ state->wr_ref = 0;
++ }
++
++ up(&state->sem);
++ return 0;
++}
++
++
++int pxa_audio_attach(struct inode *inode, struct file *file,
++ audio_state_t *state)
++{
++ audio_stream_t *is = state->input_stream;
++ audio_stream_t *os = state->output_stream;
++ int err;
++
++ down(&state->sem);
++
++ /* access control */
++ err = -ENODEV;
++ if ((file->f_mode & FMODE_WRITE) && !os)
++ goto out;
++ if ((file->f_mode & FMODE_READ) && !is)
++ goto out;
++ err = -EBUSY;
++ if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
++ goto out;
++ if ((file->f_mode & FMODE_READ) && state->rd_ref)
++ goto out;
++
++ /* request DMA channels */
++ if (file->f_mode & FMODE_WRITE) {
++ err = pxa_request_dma(os->name, DMA_PRIO_LOW,
++ audio_dma_irq, os);
++ if (err < 0)
++ goto out;
++ os->dma_ch = err;
++ }
++ if (file->f_mode & FMODE_READ) {
++ err = pxa_request_dma(is->name, DMA_PRIO_LOW,
++ audio_dma_irq, is);
++ if (err < 0) {
++ if (file->f_mode & FMODE_WRITE) {
++ *os->drcmr = 0;
++ pxa_free_dma(os->dma_ch);
++ }
++ goto out;
++ }
++ is->dma_ch = err;
++ }
++
++ file->private_data = state;
++ file->f_op->release = audio_release;
++ file->f_op->write = audio_write;
++ file->f_op->read = audio_read;
++ file->f_op->mmap = audio_mmap;
++ file->f_op->poll = audio_poll;
++ file->f_op->ioctl = audio_ioctl;
++ file->f_op->llseek = no_llseek;
++
++ if ((file->f_mode & FMODE_WRITE)) {
++ state->wr_ref = 1;
++ os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
++ os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
++ os->output = 1;
++ os->mapped = 0;
++ init_waitqueue_head(&os->frag_wq);
++ init_waitqueue_head(&os->stop_wq);
++ *os->drcmr = os->dma_ch | DRCMR_MAPVLD;
++ }
++ if (file->f_mode & FMODE_READ) {
++ state->rd_ref = 1;
++ is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
++ is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
++ is->output = 0;
++ is->mapped = 0;
++ init_waitqueue_head(&is->frag_wq);
++ init_waitqueue_head(&is->stop_wq);
++ *is->drcmr = is->dma_ch | DRCMR_MAPVLD;
++ }
++
++ err = 0;
++
++out:
++ up(&state->sem);
++ return err;
++}
++
++EXPORT_SYMBOL(pxa_audio_attach);
++EXPORT_SYMBOL(pxa_audio_clear_buf);
++
++MODULE_AUTHOR("Nicolas Pitre, MontaVista Software Inc.");
++MODULE_DESCRIPTION("audio interface for the Cotula chip");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.15gum/sound/oss/pxa-audio.h
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/sound/oss/pxa-audio.h
+@@ -0,0 +1,54 @@
++/*
++ * linux/drivers/sound/pxa-audio.h -- audio interface for the Cotula chip
++ *
++ * Author: Nicolas Pitre
++ * Created: Aug 15, 2001
++ * Copyright: MontaVista Software Inc.
++ *
++ * 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.
++ */
++
++typedef struct {
++ int offset; /* current buffer position */
++ char *data; /* actual buffer */
++ pxa_dma_desc *dma_desc; /* pointer to the starting desc */
++ int master; /* owner for buffer allocation, contain size whn true */
++} audio_buf_t;
++
++typedef struct {
++ char *name; /* stream identifier */
++ audio_buf_t *buffers; /* pointer to audio buffer array */
++ u_int usr_frag; /* user fragment index */
++ u_int dma_frag; /* DMA fragment index */
++ u_int fragsize; /* fragment size */
++ u_int nbfrags; /* number of fragments */
++ u_int dma_ch; /* DMA channel number */
++ dma_addr_t dma_desc_phys; /* phys addr of descriptor ring */
++ u_int descs_per_frag; /* nbr descriptors per fragment */
++ int bytecount; /* nbr of processed bytes */
++ int fragcount; /* nbr of fragment transitions */
++ struct semaphore sem; /* account for fragment usage */
++ wait_queue_head_t frag_wq; /* for poll(), etc. */
++ wait_queue_head_t stop_wq; /* for users of DCSR_STOPIRQEN */
++ u_long dcmd; /* DMA descriptor dcmd field */
++ volatile u32 *drcmr; /* the DMA request channel to use */
++ u_long dev_addr; /* device physical address for DMA */
++ int mapped:1; /* mmap()'ed buffers */
++ int output:1; /* 0 for input, 1 for output */
++} audio_stream_t;
++
++typedef struct {
++ audio_stream_t *output_stream;
++ audio_stream_t *input_stream;
++ int dev_dsp; /* audio device handle */
++ int rd_ref:1; /* open reference for recording */
++ int wr_ref:1; /* open reference for playback */
++ int (*client_ioctl)(struct inode *, struct file *, uint, ulong);
++ struct semaphore sem; /* prevent races in attach/release */
++} audio_state_t;
++
++extern int pxa_audio_attach(struct inode *inode, struct file *file,
++ audio_state_t *state);
++extern void pxa_audio_clear_buf(audio_stream_t *s);
diff --git a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch
new file mode 100644
index 0000000000..e989c72b70
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch
@@ -0,0 +1,117 @@
+Status: WORKS
+PXA CPU enhancements
+
+from patch 1667:
+- 64K PTEs
+from hh.org-cvs:
+- support in pxa_gpio_mode for active low
+
+#
+# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
+#
+
+Index: linux-2.6.15gum/arch/arm/mm/proc-xscale.S
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mm/proc-xscale.S
++++ linux-2.6.15gum/arch/arm/mm/proc-xscale.S
+@@ -444,11 +444,62 @@ ENTRY(cpu_xscale_set_pte)
+ movne r2, #0 @ no -> fault
+
+ str r2, [r0] @ hardware version
++
++ @ We try to map 64K page entries when possible.
++ @ We do that for kernel space only since the usage pattern from
++ @ the setting of VM area is quite simple. User space is not worth
++ @ the implied complexity because of ever randomly changing PTEs
++ @ (page aging, swapout, etc) requiring constant coherency checks.
++ @ Since PTEs are usually set in increasing order, we test the
++ @ possibility for a large page only when given the last PTE of a
++ @ 64K boundary.
++ tsteq r1, #L_PTE_USER
++ andeq r1, r0, #(15 << 2)
++ teqeq r1, #(15 << 2)
++ beq 1f
++
+ mov ip, #0
+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
++ @ See if we have 16 identical PTEs but with consecutive base addresses
++1: bic r3, r2, #0x0000f000
++ mov r1, #0x0000f000
++2: eor r2, r2, r3
++ teq r2, r1
++ bne 4f
++ subs r1, r1, #0x00001000
++ ldr r2, [r0, #-4]!
++ bne 2b
++ eors r2, r2, r3
++ bne 4f
++
++ @ Now create our LARGE PTE from the current EXT one.
++ bic r3, r3, #PTE_TYPE_MASK
++ orr r3, r3, #PTE_TYPE_LARGE
++ and r2, r3, #0x30 @ EXT_AP --> LARGE_AP0
++ orr r2, r2, r2, lsl #2 @ add LARGE_AP1
++ orr r2, r2, r2, lsl #4 @ add LARGE_AP3 + LARGE_AP2
++ and r1, r3, #0x3c0 @ EXT_TEX
++ bic r3, r3, #0x3c0
++ orr r2, r2, r1, lsl #(12 - 6) @ --> LARGE_TEX
++ orr r2, r2, r3 @ add remaining bits
++
++ @ then put it in the pagetable
++ mov r3, r2
++3: strd r2, [r0], #8
++ tst r0, #(15 << 2)
++ bne 3b
++
++ @ Then sync the 2 corresponding cache lines
++ sub r0, r0, #(16 << 2)
++ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
++4: orr r0, r0, #(15 << 2)
++ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
++ mov ip, #0
++ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
++ mov pc, lr
+
+ .ltorg
+
+Index: linux-2.6.15gum/include/asm-arm/arch-pxa/pxa-regs.h
+===================================================================
+--- linux-2.6.15gum.orig/include/asm-arm/arch-pxa/pxa-regs.h
++++ linux-2.6.15gum/include/asm-arm/arch-pxa/pxa-regs.h
+@@ -1348,6 +1348,7 @@
+ #define GPIO_ALT_FN_2_OUT 0x280
+ #define GPIO_ALT_FN_3_IN 0x300
+ #define GPIO_ALT_FN_3_OUT 0x380
++#define GPIO_ACTIVE_LOW 0x1000
+ #define GPIO_MD_MASK_NR 0x07f
+ #define GPIO_MD_MASK_DIR 0x080
+ #define GPIO_MD_MASK_FN 0x300
+@@ -1598,6 +1599,25 @@
+ #define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */
+ #define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */
+
++#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */
++#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */
++#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */
++#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */
++#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */
++#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */
++#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */
++#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */
++#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */
++#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */
++#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */
++#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */
++#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */
++#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */
++#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */
++#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */
++#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */
++#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */
++
+
+ /*
+ * SSP Serial Port Registers
diff --git a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch
new file mode 100644
index 0000000000..be522995f6
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch
@@ -0,0 +1,403 @@
+Status: WORKS
+PXA CPU frequency change support
+added mods from Stefan Eletzhofer and Lothar Weissmann
+
+#
+# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
+#
+
+Index: linux-2.6.15gum/arch/arm/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/Kconfig
++++ linux-2.6.15gum/arch/arm/Kconfig
+@@ -549,7 +549,7 @@ config XIP_PHYS_ADDR
+
+ endmenu
+
+-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1)
++if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1 || ARCH_PXA)
+
+ menu "CPU Frequency scaling"
+
+@@ -578,6 +578,12 @@ config CPU_FREQ_INTEGRATOR
+
+ endmenu
+
++config CPU_FREQ_PXA
++ bool
++ depends on CPU_FREQ && ARCH_PXA
++ default y
++ select CPU_FREQ_DEFAULT_GOV_USERSPACE
++
+ endif
+
+ menu "Floating point emulation"
+Index: linux-2.6.15gum/arch/arm/mach-pxa/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/Makefile
++++ linux-2.6.15gum/arch/arm/mach-pxa/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
+ # Misc features
+ obj-$(CONFIG_PM) += pm.o sleep.o
+ obj-$(CONFIG_PXA_SSP) += ssp.o
++obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
+
+ ifeq ($(CONFIG_PXA27x),y)
+ obj-$(CONFIG_PM) += standby.o
+Index: linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c
+@@ -0,0 +1,321 @@
++/*
++ * linux/arch/arm/mach-pxa/cpu-pxa.c
++ *
++ * Copyright (C) 2002,2003 Intrinsyc Software
++ *
++ * 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
++ *
++ * History:
++ * 31-Jul-2002 : Initial version [FB]
++ * 29-Jan-2003 : added PXA255 support [FB]
++ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
++ *
++ * Note:
++ * This driver may change the memory bus clock rate, but will not do any
++ * platform specific access timing changes... for example if you have flash
++ * memory connected to CS0, you will need to register a platform specific
++ * notifier which will adjust the memory access strobes to maintain a
++ * minimum strobe width.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/cpufreq.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++#define DEBUG 0
++
++#ifdef DEBUG
++ static unsigned int freq_debug = DEBUG;
++ MODULE_PARM(freq_debug, "i");
++ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
++#else
++ #define freq_debug 0
++#endif
++
++typedef struct
++{
++ unsigned int khz;
++ unsigned int membus;
++ unsigned int cccr;
++ unsigned int div2;
++} pxa_freqs_t;
++
++/* Define the refresh period in mSec for the SDRAM and the number of rows */
++#define SDRAM_TREF 64 /* standard 64ms SDRAM */
++#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
++#define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32))
++
++#define CCLKCFG_TURBO 0x1
++#define CCLKCFG_FCS 0x2
++#define PXA25x_MIN_FREQ 99500
++#define PXA25x_MAX_FREQ 398100
++#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
++#define MDREFR_DRI_MASK 0xFFF
++
++
++/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
++static pxa_freqs_t pxa255_run_freqs[] =
++{
++ /* CPU MEMBUS CCCR DIV2*/
++ { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
++ {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
++ {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
++ {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
++ {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
++ {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
++ {0,}
++};
++#define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t))
++
++static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
++
++/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
++static pxa_freqs_t pxa255_turbo_freqs[] =
++{
++ /* CPU MEMBUS CCCR DIV2*/
++ { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
++ {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
++ {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
++ {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
++ {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
++ {0,}
++};
++#define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t))
++
++static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
++
++extern unsigned get_clk_frequency_khz(int info);
++
++/* find a valid frequency point */
++static int pxa_verify_policy(struct cpufreq_policy *policy)
++{
++ int ret;
++ struct cpufreq_frequency_table *pxa_freqs_table;
++
++ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
++ pxa_freqs_table = pxa255_run_freq_table;
++ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
++ pxa_freqs_table = pxa255_turbo_freq_table;
++ } else {
++ printk("CPU PXA: Unknown policy found. "
++ "Using CPUFREQ_POLICY_PERFORMANCE\n");
++ pxa_freqs_table = pxa255_run_freq_table;
++ }
++ ret=cpufreq_frequency_table_verify(policy, pxa_freqs_table);
++
++ if(freq_debug) {
++ printk("Verified CPU policy: %dKhz min to %dKhz max\n",
++ policy->min, policy->max);
++ }
++
++ return ret;
++}
++
++static int pxa_set_target(struct cpufreq_policy *policy,
++ unsigned int target_freq,
++ unsigned int relation)
++{
++ int idx;
++ unsigned long cpus_allowed;
++ int cpu = policy->cpu;
++ struct cpufreq_freqs freqs;
++ pxa_freqs_t *pxa_freq_settings;
++ struct cpufreq_frequency_table *pxa_freqs_table;
++ unsigned long flags;
++ unsigned int unused;
++ unsigned int preset_mdrefr, postset_mdrefr;
++
++ /*
++ * 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, 1 << cpu);
++ BUG_ON(cpu != smp_processor_id());
++
++ /* Get the current policy */
++ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
++ pxa_freq_settings = pxa255_run_freqs;
++ pxa_freqs_table = pxa255_run_freq_table;
++ }else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
++ pxa_freq_settings = pxa255_turbo_freqs;
++ pxa_freqs_table = pxa255_turbo_freq_table;
++ }else {
++ printk("CPU PXA: Unknown policy found. "
++ "Using CPUFREQ_POLICY_PERFORMANCE\n");
++ pxa_freq_settings = pxa255_run_freqs;
++ pxa_freqs_table = pxa255_run_freq_table;
++ }
++
++ /* Lookup the next frequency */
++ if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
++ target_freq, relation, &idx)) {
++ return -EINVAL;
++ }
++
++ freqs.old = policy->cur;
++ freqs.new = pxa_freq_settings[idx].khz;
++ freqs.cpu = policy->cpu;
++ if(freq_debug) {
++ printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
++ freqs.new/1000, (pxa_freq_settings[idx].div2) ?
++ (pxa_freq_settings[idx].membus/2000) :
++ (pxa_freq_settings[idx].membus/1000));
++ }
++
++ void *ramstart = phys_to_virt(0xa0000000);
++
++ /*
++ * Tell everyone what we're about to do...
++ * you should add a notify client with any platform specific
++ * Vcc changing capability
++ */
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++ /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
++ * we need to preset the smaller DRI before the change. If we're speeding
++ * up we need to set the larger DRI value after the change.
++ */
++ preset_mdrefr = postset_mdrefr = MDREFR;
++ if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
++ preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
++ MDREFR_DRI(pxa_freq_settings[idx].membus);
++ }
++ postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
++ MDREFR_DRI(pxa_freq_settings[idx].membus);
++
++ /* If we're dividing the memory clock by two for the SDRAM clock, this
++ * must be set prior to the change. Clearing the divide must be done
++ * after the change.
++ */
++ if(pxa_freq_settings[idx].div2) {
++ preset_mdrefr |= MDREFR_DB2_MASK;
++ postset_mdrefr |= MDREFR_DB2_MASK;
++ } else {
++ postset_mdrefr &= ~MDREFR_DB2_MASK;
++ }
++
++ local_irq_save(flags);
++
++ /* Set new the CCCR */
++ CCCR = pxa_freq_settings[idx].cccr;
++
++ __asm__ __volatile__(" \
++ ldr r4, [%1] ; /* load MDREFR */ \
++ b 2f ; \
++ .align 5 ; \
++1: \
++ str %4, [%1] ; /* preset the MDREFR */ \
++ mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \
++ str %5, [%1] ; /* postset the MDREFR */ \
++ \
++ b 3f ; \
++2: b 1b ; \
++3: nop ; \
++ "
++ : "=&r" (unused)
++ : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), \
++ "r" (preset_mdrefr), "r" (postset_mdrefr)
++ : "r4", "r5");
++ local_irq_restore(flags);
++
++ /*
++ * Restore the CPUs allowed mask.
++ */
++ set_cpus_allowed(current, cpus_allowed);
++
++ /*
++ * Tell everyone what we've just done...
++ * you should add a notify client with any platform specific
++ * SDRAM refresh timer adjustments
++ */
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++ return 0;
++}
++
++static int pxa_cpufreq_init(struct cpufreq_policy *policy)
++{
++ unsigned long cpus_allowed;
++ unsigned int cpu = policy->cpu;
++ int i;
++
++ cpus_allowed = current->cpus_allowed;
++
++ set_cpus_allowed(current, 1 << cpu);
++ BUG_ON(cpu != smp_processor_id());
++
++ /* set default policy and cpuinfo */
++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
++ policy->policy = CPUFREQ_POLICY_PERFORMANCE;
++ policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
++ policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
++ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
++ policy->cur = get_clk_frequency_khz(0); /* current freq */
++ policy->min = policy->max = policy->cur;
++
++ /* Generate the run cpufreq_frequency_table struct */
++ for(i=0;i<NUM_RUN_FREQS;i++) {
++ pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
++ pxa255_run_freq_table[i].index = i;
++ }
++ pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
++ /* Generate the turbo cpufreq_frequency_table struct */
++ for(i=0;i<NUM_TURBO_FREQS;i++) {
++ pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
++ pxa255_turbo_freq_table[i].index = i;
++ }
++ pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
++
++ set_cpus_allowed(current, cpus_allowed);
++ printk(KERN_INFO "PXA CPU frequency change support initialized\n");
++
++ return 0;
++}
++
++static struct cpufreq_driver pxa_cpufreq_driver = {
++ .verify = pxa_verify_policy,
++ .target = pxa_set_target,
++ .init = pxa_cpufreq_init,
++ .name = "PXA25x",
++};
++
++static int __init pxa_cpu_init(void)
++{
++ return cpufreq_register_driver(&pxa_cpufreq_driver);
++}
++
++static void __exit pxa_cpu_exit(void)
++{
++ cpufreq_unregister_driver(&pxa_cpufreq_driver);
++}
++
++
++MODULE_AUTHOR ("Intrinsyc Software Inc.");
++MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
++MODULE_LICENSE("GPL");
++module_init(pxa_cpu_init);
++module_exit(pxa_cpu_exit);
++
+Index: linux-2.6.15gum/Documentation/cpu-freq/user-guide.txt
+===================================================================
+--- linux-2.6.15gum.orig/Documentation/cpu-freq/user-guide.txt
++++ linux-2.6.15gum/Documentation/cpu-freq/user-guide.txt
+@@ -18,7 +18,7 @@
+ Contents:
+ ---------
+ 1. Supported Architectures and Processors
+-1.1 ARM
++1.1 ARM, PXA
+ 1.2 x86
+ 1.3 sparc64
+ 1.4 ppc
+@@ -37,14 +37,15 @@ Contents:
+ 1. Supported Architectures and Processors
+ =========================================
+
+-1.1 ARM
+--------
++1.1 ARM, PXA
++------------
+
+ The following ARM processors are supported by cpufreq:
+
+ ARM Integrator
+ ARM-SA1100
+ ARM-SA1110
++Intel PXA
+
+
+ 1.2 x86
diff --git a/recipes/linux/linux-gumstix-2.6.15/board-init.patch b/recipes/linux/linux-gumstix-2.6.15/board-init.patch
new file mode 100644
index 0000000000..062e97f029
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/board-init.patch
@@ -0,0 +1,98 @@
+Index: linux-2.6.15gum/arch/arm/mach-pxa/gumstix.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/arch/arm/mach-pxa/gumstix.c
+@@ -0,0 +1,93 @@
++/*
++ * linux/arch/arm/mach-pxa/gumstix.c
++ *
++ * Support for the Gumstix computer platform
++ *
++ * Author: Craig Hughes
++ * Created: December 8 2004
++ * Copyright: (C) 2004, Craig Hughes
++ *
++ * 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 <asm/types.h>
++
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/arch/udc.h>
++#include <asm/arch/mmc.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/gumstix.h>
++
++#include "generic.h"
++
++static int gumstix_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data)
++{
++ // Set up MMC controller
++ pxa_gpio_mode(GPIO6_MMCCLK_MD);
++ pxa_gpio_mode(GPIO53_MMCCLK_MD);
++ pxa_gpio_mode(GPIO8_MMCCS0_MD);
++
++ return 0;
++}
++
++static struct pxamci_platform_data gumstix_mci_platform_data = {
++ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
++ .init = &gumstix_mci_init,
++};
++
++static int gumstix_udc_is_connected(void)
++{
++ return !! (GPLR(GPIO_GUMSTIX_USB_GPIOn) & GPIO_bit(GPIO_GUMSTIX_USB_GPIOn));
++}
++
++static void gumstix_udc_command(int connect_command)
++{
++ if (connect_command == PXA2XX_UDC_CMD_CONNECT) {
++ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOx_CON_MD);
++ GPSR(GPIO_GUMSTIX_USB_GPIOx) = GPIO_bit(GPIO_GUMSTIX_USB_GPIOx);
++ }
++ if (connect_command == PXA2XX_UDC_CMD_DISCONNECT) {
++ GPCR(GPIO_GUMSTIX_USB_GPIOx) = GPIO_bit(GPIO_GUMSTIX_USB_GPIOx);
++ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOx_DIS_MD);
++ }
++}
++
++static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = {
++ .udc_is_connected = gumstix_udc_is_connected,
++ .udc_command = gumstix_udc_command,
++};
++
++static struct platform_device gum_audio_device = {
++ .name = "pxa2xx-ac97",
++ .id = -1,
++};
++
++static struct platform_device *devices[] __initdata = {
++ &gum_audio_device,
++};
++
++static void __init gumstix_init(void)
++{
++ pxa_set_mci_info(&gumstix_mci_platform_data);
++ pxa_set_udc_info(&gumstix_udc_info);
++ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
++}
++
++MACHINE_START(GUMSTIX, "The Gumstix Platform")
++ .phys_ram = 0xa0000000,
++ .phys_io = 0x40000000,
++ .boot_params = 0xa0000100,
++ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
++ .timer = &pxa_timer,
++ .map_io = pxa_map_io,
++ .init_irq = pxa_init_irq,
++ .init_machine = gumstix_init,
++MACHINE_END
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch
new file mode 100644
index 0000000000..5cc3a0bcfa
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch
@@ -0,0 +1,12 @@
+Index: linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/i2c/busses/i2c-pxa.c
++++ linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c
+@@ -32,6 +32,7 @@
+ #include <linux/i2c-pxa.h>
+ #include <linux/platform_device.h>
+
++#include <asm/arch/pxa-regs.h>
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/arch/i2c.h>
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch
new file mode 100644
index 0000000000..0b93fffaef
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch
@@ -0,0 +1,14 @@
+Index: linux-2.6.15gum/drivers/mmc/pxamci.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mmc/pxamci.c
++++ linux-2.6.15gum/drivers/mmc/pxamci.c
+@@ -381,8 +381,7 @@ static void pxamci_set_ios(struct mmc_ho
+
+ if (ios->clock) {
+ unsigned int clk = CLOCKRATE / ios->clock;
+- if (CLOCKRATE / clk > ios->clock)
+- clk <<= 1;
++ if(clk > (1<<6)) clk = (1<<6);
+ host->clkrt = fls(clk) - 1;
+ pxa_set_cken(CKEN12_MMC, 1);
+
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch
new file mode 100644
index 0000000000..1b1662e963
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch
@@ -0,0 +1,22 @@
+Index: linux-2.6.15gum/drivers/mtd/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mtd/Kconfig
++++ linux-2.6.15gum/drivers/mtd/Kconfig
+@@ -271,7 +271,5 @@ source "drivers/mtd/devices/Kconfig"
+
+ source "drivers/mtd/nand/Kconfig"
+
+-source "drivers/mtd/onenand/Kconfig"
+-
+ endmenu
+
+Index: linux-2.6.15gum/drivers/mtd/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mtd/Makefile
++++ linux-2.6.15gum/drivers/mtd/Makefile
+@@ -25,4 +25,4 @@ obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_
+ nftl-objs := nftlcore.o nftlmount.o
+ inftl-objs := inftlcore.o inftlmount.o
+
+-obj-y += chips/ maps/ devices/ nand/ onenand/
++obj-y += chips/ maps/ devices/ nand/
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch
new file mode 100644
index 0000000000..a8d04f0e20
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch
@@ -0,0 +1,25 @@
+Index: linux-2.6.15gum/sound/oss/pxa-audio.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/pxa-audio.c
++++ linux-2.6.15gum/sound/oss/pxa-audio.c
+@@ -731,7 +731,7 @@ static int audio_mmap(struct file *file,
+ audio_buf_t *buf = &s->buffers[i];
+ if (!buf->master)
+ continue;
+- ret = remap_page_range(vma, vma->vm_start, buf->dma_desc->dsadr,
++ ret = io_remap_page_range(vma, vma_addr, buf->dma_desc->dsadr,
+ buf->master, vma->vm_page_prot);
+ if (ret)
+ return ret;
+Index: linux-2.6.15gum/sound/oss/pxa-audio.h
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/pxa-audio.h
++++ linux-2.6.15gum/sound/oss/pxa-audio.h
+@@ -52,3 +52,7 @@ typedef struct {
+ extern int pxa_audio_attach(struct inode *inode, struct file *file,
+ audio_state_t *state);
+ extern void pxa_audio_clear_buf(audio_stream_t *s);
++
++#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
++#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
++#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch
new file mode 100644
index 0000000000..6d2f2b3267
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch
@@ -0,0 +1,64 @@
+Index: linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/cpu-pxa.c
++++ linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c
+@@ -60,7 +60,7 @@ typedef struct
+
+ /* Define the refresh period in mSec for the SDRAM and the number of rows */
+ #define SDRAM_TREF 64 /* standard 64ms SDRAM */
+-#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
++#define SDRAM_ROWS 8192 /* 64MB=8192 32MB=4096 */
+ #define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32))
+
+ #define CCLKCFG_TURBO 0x1
+@@ -136,7 +136,7 @@ static int pxa_set_target(struct cpufreq
+ unsigned int relation)
+ {
+ int idx;
+- unsigned long cpus_allowed;
++ cpumask_t cpus_allowed;
+ int cpu = policy->cpu;
+ struct cpufreq_freqs freqs;
+ pxa_freqs_t *pxa_freq_settings;
+@@ -144,6 +144,7 @@ static int pxa_set_target(struct cpufreq
+ unsigned long flags;
+ unsigned int unused;
+ unsigned int preset_mdrefr, postset_mdrefr;
++ void *ramstart;
+
+ /*
+ * Save this threads cpus_allowed mask.
+@@ -154,7 +155,7 @@ static int pxa_set_target(struct cpufreq
+ * Bind to the specified CPU. When this call returns,
+ * we should be running on the right CPU.
+ */
+- set_cpus_allowed(current, 1 << cpu);
++ set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ BUG_ON(cpu != smp_processor_id());
+
+ /* Get the current policy */
+@@ -187,7 +188,7 @@ static int pxa_set_target(struct cpufreq
+ (pxa_freq_settings[idx].membus/1000));
+ }
+
+- void *ramstart = phys_to_virt(0xa0000000);
++ ramstart = phys_to_virt(0xa0000000);
+
+ /*
+ * Tell everyone what we're about to do...
+@@ -260,13 +261,13 @@ static int pxa_set_target(struct cpufreq
+
+ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
+ {
+- unsigned long cpus_allowed;
++ cpumask_t cpus_allowed;
+ unsigned int cpu = policy->cpu;
+ int i;
+
+ cpus_allowed = current->cpus_allowed;
+
+- set_cpus_allowed(current, 1 << cpu);
++ set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ BUG_ON(cpu != smp_processor_id());
+
+ /* set default policy and cpuinfo */
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch
new file mode 100644
index 0000000000..574ac1ac62
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch
@@ -0,0 +1,12 @@
+Index: linux-2.6.15gum/drivers/serial/pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/serial/pxa.c
++++ linux-2.6.15gum/drivers/serial/pxa.c
+@@ -277,7 +277,6 @@ static unsigned int serial_pxa_get_mctrl
+ unsigned char status;
+ unsigned int ret;
+
+-return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+ status = serial_in(up, UART_MSR);
+
+ ret = 0;
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch
new file mode 100644
index 0000000000..d51597f94b
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch
@@ -0,0 +1,14 @@
+Index: linux-2.6.15gum/drivers/usb/gadget/ether.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/usb/gadget/ether.c
++++ linux-2.6.15gum/drivers/usb/gadget/ether.c
+@@ -2328,7 +2328,9 @@ autoconf_fail:
+ #ifdef DEV_CONFIG_CDC
+ /* pxa25x only does CDC subset; often used with RNDIS */
+ } else if (cdc) {
++#ifdef DEV_CONFIG_CDC
+ control_intf.bNumEndpoints = 0;
++#endif
+ /* FIXME remove endpoint from descriptor list */
+ #endif
+ }
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch
new file mode 100644
index 0000000000..df4a46e030
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch
@@ -0,0 +1,25 @@
+Index: linux-2.6.15gum/drivers/serial/pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/serial/pxa.c
++++ linux-2.6.15gum/drivers/serial/pxa.c
+@@ -246,15 +246,19 @@ serial_pxa_irq(int irq, void *dev_id, st
+ struct uart_pxa_port *up = (struct uart_pxa_port *)dev_id;
+ unsigned int iir, lsr;
+
++ serial_out(up, UART_MCR, serial_in(up, UART_MCR) & ~UART_MCR_RTS); // Clear RTS
+ iir = serial_in(up, UART_IIR);
+ if (iir & UART_IIR_NO_INT)
+- return IRQ_NONE;
++ {
++ //printk(KERN_WARNING "serial_pxa_irq: odd -- interrupt triggered, but no interrupt in IIR: %08x\n",iir);
++ }
+ lsr = serial_in(up, UART_LSR);
+ if (lsr & UART_LSR_DR)
+ receive_chars(up, &lsr, regs);
+ check_modem_status(up);
+ if (lsr & UART_LSR_THRE)
+ transmit_chars(up);
++ serial_out(up, UART_MCR, serial_in(up, UART_MCR) | UART_MCR_RTS); // Assert RTS
+ return IRQ_HANDLED;
+ }
+
diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch
new file mode 100644
index 0000000000..fcef7c27c3
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch
@@ -0,0 +1,70 @@
+Index: linux-2.6.15gum/drivers/serial/pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/serial/pxa.c
++++ linux-2.6.15gum/drivers/serial/pxa.c
+@@ -58,6 +58,8 @@ struct uart_pxa_port {
+ unsigned int lsr_break_flag;
+ unsigned int cken;
+ char *name;
++ unsigned int msr; //djf
++ unsigned int lsr; //djf
+ };
+
+ static inline unsigned int serial_in(struct uart_pxa_port *up, int offset)
+@@ -169,6 +171,7 @@ receive_chars(struct uart_pxa_port *up,
+
+ ignore_char:
+ *status = serial_in(up, UART_LSR);
++ up->lsr = *status;
+ } while ((*status & UART_LSR_DR) && (max_count-- > 0));
+ tty_flip_buffer_push(tty);
+ }
+@@ -221,7 +224,7 @@ static inline void check_modem_status(st
+ int status;
+
+ status = serial_in(up, UART_MSR);
+-
++ up->msr = status;
+ if ((status & UART_MSR_ANY_DELTA) == 0)
+ return;
+
+@@ -253,6 +256,7 @@ serial_pxa_irq(int irq, void *dev_id, st
+ //printk(KERN_WARNING "serial_pxa_irq: odd -- interrupt triggered, but no interrupt in IIR: %08x\n",iir);
+ }
+ lsr = serial_in(up, UART_LSR);
++ up->lsr = lsr;
+ if (lsr & UART_LSR_DR)
+ receive_chars(up, &lsr, regs);
+ check_modem_status(up);
+@@ -269,7 +273,8 @@ static unsigned int serial_pxa_tx_empty(
+ unsigned int ret;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+- ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
++ //ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
++ ret = up->lsr * UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ return ret;
+@@ -281,7 +286,7 @@ static unsigned int serial_pxa_get_mctrl
+ unsigned char status;
+ unsigned int ret;
+
+- status = serial_in(up, UART_MSR);
++ status = up->msr;
+
+ ret = 0;
+ if (status & UART_MSR_DCD)
+@@ -411,10 +416,10 @@ static int serial_pxa_startup(struct uar
+ /*
+ * And clear the interrupt registers again for luck.
+ */
+- (void) serial_in(up, UART_LSR);
++ up->lsr = serial_in(up, UART_LSR);
+ (void) serial_in(up, UART_RX);
+ (void) serial_in(up, UART_IIR);
+- (void) serial_in(up, UART_MSR);
++ up->msr = serial_in(up, UART_MSR);
+
+ return 0;
+ }
diff --git a/recipes/linux/linux-gumstix-2.6.15/compact-flash.patch b/recipes/linux/linux-gumstix-2.6.15/compact-flash.patch
new file mode 100644
index 0000000000..c3913a23df
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/compact-flash.patch
@@ -0,0 +1,171 @@
+Index: linux-2.6.15gum/drivers/pcmcia/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/pcmcia/Makefile
++++ linux-2.6.15gum/drivers/pcmcia/Makefile
+@@ -68,4 +68,4 @@
+ pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
+ pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
+ pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
+-
++pxa2xx_cs-$(CONFIG_ARCH_GUMSTIX) += pxa2xx_gumstix.o
+Index: linux-2.6.15gum/drivers/pcmcia/pxa2xx_gumstix.c
+--- /dev/null
++++ linux-2.6.15gum/drivers/pcmcia/pxa2xx_gumstix.c
+@@ -0,0 +1,157 @@
++/*
++ * linux/drivers/pcmcia/pxa2xx_gumstix.c
++ *
++ * Gumstix PCMCIA specific routines. Based on Mainstone
++ *
++ * Copyright 2004, Craig Hughes <craig@gumstix.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.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++
++#include <pcmcia/ss.h>
++
++#include <asm/hardware.h>
++#include <asm/delay.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/irq.h>
++
++#include <asm/arch/gumstix.h>
++
++#include "soc_common.h"
++
++static struct pcmcia_irqs irqs[] = {
++ { 0, GUMSTIX_nPCD1_IRQ, "CF nCD" },
++ { 0, GUMSTIX_nSTSCHG_IRQ, "CF nSTSCHG" },
++};
++
++static int gumstix_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
++{
++ pxa_gpio_mode(GPIO8_RESET_MD);
++ GPSR(GPIO8_RESET) = GPIO_bit(GPIO8_RESET);
++ udelay(50);
++ GPCR(GPIO8_RESET) = GPIO_bit(GPIO8_RESET);
++
++ pxa_gpio_mode(GPIO4_nBVD1_MD);
++ pxa_gpio_mode(GPIO36_nBVD2_MD);
++ pxa_gpio_mode(GPIO11_nPCD1_MD);
++ pxa_gpio_mode(GPIO26_PRDY_nBSY0_MD);
++
++ /*
++ * Setup default state of GPIO outputs
++ * before we enable them as outputs.
++ */
++ GPSR(GPIO48_nPOE) =
++ GPIO_bit(GPIO48_nPOE) |
++ GPIO_bit(GPIO49_nPWE) |
++ GPIO_bit(GPIO50_nPIOR) |
++ GPIO_bit(GPIO51_nPIOW) |
++ GPIO_bit(GPIO52_nPCE_1) |
++ GPIO_bit(GPIO53_nPCE_2);
++
++ pxa_gpio_mode(GPIO48_nPOE_MD);
++ pxa_gpio_mode(GPIO49_nPWE_MD);
++ pxa_gpio_mode(GPIO50_nPIOR_MD);
++ pxa_gpio_mode(GPIO51_nPIOW_MD);
++ pxa_gpio_mode(GPIO52_nPCE_1_MD);
++ pxa_gpio_mode(GPIO53_nPCE_2_MD);
++ pxa_gpio_mode(GPIO54_pSKTSEL_MD);
++ pxa_gpio_mode(GPIO55_nPREG_MD);
++ pxa_gpio_mode(GPIO56_nPWAIT_MD);
++ pxa_gpio_mode(GPIO57_nIOIS16_MD);
++
++ skt->irq = GUMSTIX_PRDY_nBSY0_IRQ;
++
++ return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
++}
++
++static void gumstix_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
++{
++ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
++}
++
++static unsigned long gum_pcmcia_status;
++
++static void gumstix_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
++ struct pcmcia_state *state)
++{
++ state->detect = !(GPLR(GPIO11_nPCD1) & GPIO_bit(GPIO11_nPCD1));
++ state->ready = !!(GPLR(GPIO26_PRDY_nBSY0) & GPIO_bit(GPIO26_PRDY_nBSY0));
++ state->bvd1 = !!(GPLR(GPIO4_nBVD1) & GPIO_bit(GPIO4_nBVD1));
++ state->bvd2 = 1;
++ state->vs_3v = 0;
++ state->vs_Xv = 0;
++ state->wrprot = 0;
++}
++
++static int gumstix_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
++ const socket_state_t *state)
++{
++ return 0;
++}
++
++static void gumstix_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
++{
++ soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
++}
++
++static void gumstix_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
++{
++ soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
++}
++
++static struct pcmcia_low_level gumstix_pcmcia_ops = {
++ .owner = THIS_MODULE,
++ .hw_init = gumstix_pcmcia_hw_init,
++ .hw_shutdown = gumstix_pcmcia_hw_shutdown,
++ .socket_state = gumstix_pcmcia_socket_state,
++ .configure_socket = gumstix_pcmcia_configure_socket,
++ .socket_init = gumstix_pcmcia_socket_init,
++ .socket_suspend = gumstix_pcmcia_socket_suspend,
++ .nr = 1,
++};
++
++static struct platform_device *gumstix_pcmcia_device;
++
++static int __init gumstix_pcmcia_init(void)
++{
++ int ret;
++
++ gumstix_pcmcia_device = kmalloc(sizeof(*gumstix_pcmcia_device), GFP_KERNEL);
++ if (!gumstix_pcmcia_device)
++ return -ENOMEM;
++ memset(gumstix_pcmcia_device, 0, sizeof(*gumstix_pcmcia_device));
++ gumstix_pcmcia_device->name = "pxa2xx-pcmcia";
++ gumstix_pcmcia_device->dev.platform_data = &gumstix_pcmcia_ops;
++
++ ret = platform_device_register(gumstix_pcmcia_device);
++ if (ret)
++ kfree(gumstix_pcmcia_device);
++
++ return ret;
++}
++
++static void __exit gumstix_pcmcia_exit(void)
++{
++ /*
++ * This call is supposed to free our gumstix_pcmcia_device.
++ * Unfortunately platform_device don't have a free method, and
++ * we can't assume it's free of any reference at this point so we
++ * can't free it either.
++ */
++ platform_device_unregister(gumstix_pcmcia_device);
++}
++
++fs_initcall(gumstix_pcmcia_init);
++module_exit(gumstix_pcmcia_exit);
++
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch b/recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch
new file mode 100644
index 0000000000..875d316f3e
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch
@@ -0,0 +1,53 @@
+Index: linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/cpu-pxa.c
++++ linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c
+@@ -65,8 +65,8 @@ typedef struct
+
+ #define CCLKCFG_TURBO 0x1
+ #define CCLKCFG_FCS 0x2
+-#define PXA25x_MIN_FREQ 99500
+-#define PXA25x_MAX_FREQ 398100
++#define PXA25x_MIN_FREQ 99533
++#define PXA25x_MAX_FREQ 530842
+ #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
+ #define MDREFR_DRI_MASK 0xFFF
+
+@@ -75,12 +75,14 @@ typedef struct
+ static pxa_freqs_t pxa255_run_freqs[] =
+ {
+ /* CPU MEMBUS CCCR DIV2*/
+- { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
+- {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
+- {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
+- {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
+- {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
+- {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
++ { 99533, 99533, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
++ {132710, 132710, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
++ {199066, 99533, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
++ {265421, 132710, 0x143, 0}, /* run=265, turbo=265, PXbus=133, SDRAM=133 */
++ {331776, 165888, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
++ {398131, 99533, 0x161, 0}, /* run=398, turbo=398, PXbus=99, SDRAM=99 */
++ {398131, 132710, 0x1c3, 0}, /* run=265, turbo=398, PXbus=133, SDRAM=133 */
++ {530842, 132710, 0x163, 0}, /* run=531, turbo=531, PXbus=133, SDRAM=133 */
+ {0,}
+ };
+ #define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t))
+@@ -91,11 +93,11 @@ static struct cpufreq_frequency_table px
+ static pxa_freqs_t pxa255_turbo_freqs[] =
+ {
+ /* CPU MEMBUS CCCR DIV2*/
+- { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
+- {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
+- {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
+- {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
+- {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
++ { 99533, 99533, 0x121, 1}, /* run=99, turbo= 99, PXbus=99, SDRAM=50 */
++ {149299, 99533, 0x1a1, 0}, /* run=99, turbo=149, PXbus=99, SDRAM=99 */
++ {199066, 99533, 0x221, 0}, /* run=99, turbo=199, PXbus=99, SDRAM=99 */
++ {298598, 99533, 0x321, 0}, /* run=99, turbo=299, PXbus=99, SDRAM=99 */
++ {398131, 99533, 0x241, 1}, /* run=199, turbo=398, PXbus=99, SDRAM=50 */
+ {0,}
+ };
+ #define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t))
diff --git a/recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch b/recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch
new file mode 100644
index 0000000000..5903ab275b
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch
@@ -0,0 +1,42 @@
+Index: linux-2.6.15gum/drivers/cpufreq/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/cpufreq/Kconfig
++++ linux-2.6.15gum/drivers/cpufreq/Kconfig
+@@ -52,7 +52,7 @@ config CPU_FREQ_STAT_DETAILS
+
+ choice
+ prompt "Default CPUFreq governor"
+- default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110
++ default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 || CPU_FREQ_PXA
+ default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+ help
+ This option sets which CPUFreq governor shall be loaded at
+@@ -75,6 +75,14 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE
+ program shall be able to set the CPU dynamically without having
+ to enable the userspace governor manually.
+
++config CPU_FREQ_DEFAULT_GOV_ONDEMAND
++ bool "ondemand"
++ select CPU_FREQ_GOV_ONDEMAND
++ help
++ Use the CPUFreq governor 'ondemand' as default. This sets
++ the frequency dynamically based on CPU load, throttling up
++ and down as necessary.
++
+ endchoice
+
+ config CPU_FREQ_GOV_PERFORMANCE
+Index: linux-2.6.15gum/include/linux/cpufreq.h
+===================================================================
+--- linux-2.6.15gum.orig/include/linux/cpufreq.h
++++ linux-2.6.15gum/include/linux/cpufreq.h
+@@ -268,6 +268,9 @@ extern struct cpufreq_governor cpufreq_g
+ #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
+ extern struct cpufreq_governor cpufreq_gov_userspace;
+ #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
++#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND)
++extern struct cpufreq_governor cpufreq_gov_dbs;
++#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs;
+ #endif
+
+
diff --git a/recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix b/recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix
new file mode 100644
index 0000000000..24c1aca43f
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix
@@ -0,0 +1,995 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15
+# Thu Jan 19 11:07:15 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION="gum"
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SHMEM is not set
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System Type
+#
+# 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_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_PXA=y
+# 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_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# Intel PXA2xx Implementations
+#
+CONFIG_ARCH_GUMSTIX=y
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_GUMSTIX_ORIG is not set
+CONFIG_ARCH_GUMSTIX_F=y
+CONFIG_PXA25x=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+CONFIG_PROC_GPIO=m
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=m
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f02 rootfstype=jffs2 reboot=cold,hard"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# 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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_GUMSTIX=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 is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+# CONFIG_BT_HCIBLUECARD is not set
+# CONFIG_BT_HCIBTUART is not set
+# CONFIG_BT_HCIVHCI is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+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
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# 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=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# 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 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+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_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_MULTI_PHYSMAP is not set
+CONFIG_MTD_GUMSTIX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_RAMTD is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=m
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# 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
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_SMC91X=m
+CONFIG_SMC91X_GUMSTIX=m
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# 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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=m
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# 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
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=m
+CONFIG_SND_PXA2XX_AC97=m
+
+#
+# PCMCIA devices
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_SOUND_WM97XX is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_GUMSTIX=m
+# CONFIG_USB_GADGET_NET2280 is not set
+CONFIG_USB_GADGET_PXA2XX=y
+CONFIG_USB_PXA2XX=m
+# CONFIG_USB_PXA2XX_SMALL 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_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_PXA=m
+# CONFIG_MMC_WBSD is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+CONFIG_JFS=m
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# 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="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# 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_JFFS_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_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# 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
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+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=m
+# 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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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_DES is not set
+# 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=m
+# 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_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/recipes/linux/linux-gumstix-2.6.15/defconfig.patch b/recipes/linux/linux-gumstix-2.6.15/defconfig.patch
new file mode 100644
index 0000000000..0cafd7e774
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/defconfig.patch
@@ -0,0 +1,766 @@
+Index: linux-2.6.15gum/arch/arm/configs/gumstix_defconfig
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/arch/arm/configs/gumstix_defconfig
+@@ -0,0 +1,761 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_BROKEN_ON_SMP=y
++
++#
++# General setup
++#
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++# CONFIG_AUDIT is not set
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_HOTPLUG=y
++# CONFIG_IKCONFIG is not set
++CONFIG_EMBEDDED=y
++# CONFIG_KALLSYMS is not set
++# CONFIG_FUTEX is not set
++# CONFIG_EPOLL is not set
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# 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_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP3XX is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++CONFIG_ARCH_PXA=y
++# 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_ARCH_VERSATILE_PB is not set
++# CONFIG_ARCH_IMX is not set
++
++#
++# Intel PXA2xx Implementations
++#
++CONFIG_ARCH_GUMSTIX=y
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_MAINSTONE is not set
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_ARCH_GUMSTIX_ORIG is not set
++CONFIG_ARCH_GUMSTIX_F=y
++CONFIG_PXA25x=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_MINICACHE=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++CONFIG_XSCALE_PMU=y
++
++#
++# General setup
++#
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_PXA=y
++# CONFIG_CPU_FREQ_PROC_INTF is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
++CONFIG_CPU_FREQ_GOV_POWERSAVE=m
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++CONFIG_PROC_GPIO=m
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_PCMCIA_DEBUG is not set
++# CONFIG_TCIC is not set
++CONFIG_PCMCIA_PXA2XX=m
++
++#
++# At least one math 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
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f02 rootfstype=jffs2 reboot=cold,hard"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++
++#
++# 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=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
++# 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 is not set
++# 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 is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++CONFIG_MTD_COMPLEX_MAPPINGS=y
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x00400000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++CONFIG_MTD_GUMSTIX=y
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_EDB7312 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++CONFIG_PACKET_MMAP=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_UNIX=m
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER 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_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_TUNNEL is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETFILTER is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP 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_NET_DIVERT is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_HW_FLOWCONTROL is not set
++
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_GUMSTIX=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_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++# CONFIG_BT_HCIUART_BCSP is not set
++# CONFIG_BT_HCIDTL1 is not set
++# CONFIG_BT_HCIBT3C is not set
++# CONFIG_BT_HCIBLUECARD is not set
++# CONFIG_BT_HCIBTUART is not set
++CONFIG_BT_HCIVHCI=m
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=m
++CONFIG_SMC91X=m
++CONFIG_SMC91X_GUMSTIX=m
++
++#
++# Ethernet (1000 Mbit)
++#
++
++#
++# Ethernet (10000 Mbit)
++#
++
++#
++# Token Ring devices
++#
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# PCMCIA network device support
++#
++# CONFIG_NET_PCMCIA is not set
++
++#
++# 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
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++CONFIG_IDE=m
++CONFIG_BLK_DEV_IDE=m
++
++#
++# Please see Documentation/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++# CONFIG_BLK_DEV_IDEDISK is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# CONFIG_IDE_TASKFILE_IO is not set
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_IDE_GENERIC=m
++# CONFIG_IDE_ARM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_SCSI is not set
++
++#
++# Fusion MPT device support
++#
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# I2O device support
++#
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=m
++
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_CT82C710 is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_SA1100_WATCHDOG=y
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++CONFIG_SA1100_RTC=m
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# File systems
++#
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_SYSFS=y
++# CONFIG_DEVFS_FS is not set
++# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++
++#
++# 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_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++CONFIG_JFFS2_COMPRESSION_OPTIONS=y
++CONFIG_JFFS2_ZLIB=y
++CONFIG_JFFS2_RTIME=y
++CONFIG_JFFS2_RUBIN=y
++# CONFIG_JFFS2_CMODE_NONE is not set
++# CONFIG_JFFS2_CMODE_PRIORITY is not set
++CONFIG_JFFS2_CMODE_SIZE=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_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++# CONFIG_EXPORTFS is not set
++CONFIG_SUNRPC=m
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# 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
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++
++#
++# Native Language Support
++#
++CONFIG_NLS=m
++CONFIG_NLS_DEFAULT="iso8859-1"
++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=m
++# 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
++
++#
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# USB support
++#
++
++#
++# USB Gadget Support
++#
++CONFIG_USB_GADGET=m
++CONFIG_USB_GADGET_GUMSTIX=m
++# CONFIG_USB_GADGET_NET2280 is not set
++CONFIG_USB_GADGET_PXA2XX=y
++CONFIG_USB_PXA2XX=m
++# CONFIG_USB_PXA2XX_SMALL is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_SA1100 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FILE_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++
++#
++# MMC/SD Card support
++#
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_PXA=m
++
++#
++# Kernel hacking
++#
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
diff --git a/recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch b/recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch
new file mode 100644
index 0000000000..34399a9578
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch
@@ -0,0 +1,32 @@
+Index: linux-2.6.15gum/arch/arm/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/boot/compressed/misc.c
++++ linux-2.6.15gum/arch/arm/boot/compressed/misc.c
+@@ -280,7 +280,6 @@ void flush_window(void)
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+- putstr(".");
+ }
+
+ #ifndef arch_error
+@@ -312,9 +311,7 @@ decompress_kernel(ulg output_start, ulg
+ arch_decomp_setup();
+
+ makecrc();
+- putstr("Uncompressing Linux...");
+ gunzip();
+- putstr(" done, booting the kernel.\n");
+ return output_ptr;
+ }
+ #else
+@@ -326,9 +323,7 @@ int main()
+ output_data = output_buffer;
+
+ makecrc();
+- putstr("Uncompressing Linux...");
+ gunzip();
+- putstr("done.\n");
+ return 0;
+ }
+ #endif
diff --git a/recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch b/recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch
new file mode 100644
index 0000000000..1e6ac5bbda
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch
@@ -0,0 +1,26 @@
+Index: linux-2.6.15gum/drivers/net/smc91x.h
+===================================================================
+--- linux-2.6.15gum.orig/drivers/net/smc91x.h
++++ linux-2.6.15gum/drivers/net/smc91x.h
+@@ -55,6 +55,21 @@
+ #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
+ #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+
++#elif defined(CONFIG_ARCH_GUMSTIX)
++#define SMC_CAN_USE_8BIT 0
++#define SMC_CAN_USE_16BIT 1
++#define SMC_CAN_USE_32BIT 0
++#define SMC_NOWAIT 1
++#define SMC_USE_PXA_DMA 1
++#define SMC_IO_SHIFT 0
++#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 RPC_LSA_DEFAULT RPC_LED_100_10
++#define RPC_LSB_DEFAULT RPC_LED_TX_RX
++
++
+ #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6)
+
+ /* We can only do 16-bit reads and writes in the static memory space. */
diff --git a/recipes/linux/linux-gumstix-2.6.15/flash.patch b/recipes/linux/linux-gumstix-2.6.15/flash.patch
new file mode 100644
index 0000000000..b0ec106770
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/flash.patch
@@ -0,0 +1,171 @@
+Index: linux-2.6.15gum/drivers/mtd/maps/gumstix-flash.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/mtd/maps/gumstix-flash.c
+@@ -0,0 +1,136 @@
++/*
++ * Map driver for the Gumstix platform
++ *
++ * Author: Craig Hughes
++ *
++ * 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/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <asm/arch/gumstix.h>
++
++
++#define ROM_ADDR 0x00000000
++#define FLASH_ADDR 0x00000000
++
++#define WINDOW_SIZE 64*1024*1024
++
++static struct map_info gumstix_flash_maps[1] = { {
++ .name = "Gumstix Flash ROM",
++ .size = WINDOW_SIZE,
++ .phys = FLASH_ADDR,
++ .bankwidth = 2,
++} };
++
++static struct mtd_partition gumstix_flash_partitions[] = {
++ {
++ .name = "Bootloader",
++ .size = 0x00040000,
++ .offset = FLASH_ADDR
++ },{
++ .name = "RootFS",
++ .size = MTDPART_SIZ_FULL,
++ .offset = MTDPART_OFS_APPEND
++ }
++};
++
++static struct mtd_info *mymtds[1];
++static struct mtd_partition *parsed_parts[1];
++static int nr_parsed_parts[1];
++
++static const char *probes[] = { NULL };
++
++static int __init gumstix_flashmap_init(void)
++{
++ int ret = 0, i;
++
++ for (i = 0; i < 1; i++) {
++ gumstix_flash_maps[i].virt = ioremap(gumstix_flash_maps[i].phys, WINDOW_SIZE);
++ if (!gumstix_flash_maps[i].virt) {
++ printk(KERN_WARNING "Failed to ioremap %s\n", gumstix_flash_maps[i].name);
++ if (!ret)
++ ret = -ENOMEM;
++ continue;
++ }
++ simple_map_init(&gumstix_flash_maps[i]);
++
++ printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
++ gumstix_flash_maps[i].name, gumstix_flash_maps[i].phys,
++ gumstix_flash_maps[i].bankwidth * 8);
++
++ mymtds[i] = do_map_probe("cfi_probe", &gumstix_flash_maps[i]);
++
++ if (!mymtds[i]) {
++ iounmap((void *)gumstix_flash_maps[i].virt);
++ if (gumstix_flash_maps[i].cached)
++ iounmap(gumstix_flash_maps[i].cached);
++ if (!ret)
++ ret = -EIO;
++ continue;
++ }
++ mymtds[i]->owner = THIS_MODULE;
++
++ ret = parse_mtd_partitions(mymtds[i], probes,
++ &parsed_parts[i], 0);
++
++ if (ret > 0)
++ nr_parsed_parts[i] = ret;
++ }
++
++ if (!mymtds[0])
++ return ret;
++
++ for (i = 0; i < 1; i++) {
++ if (!mymtds[i]) {
++ printk(KERN_WARNING "%s is absent. Skipping\n", gumstix_flash_maps[i].name);
++ } else if (nr_parsed_parts[i]) {
++ add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]);
++ } else if (!i) {
++ printk("Using static partitions on %s\n", gumstix_flash_maps[i].name);
++ add_mtd_partitions(mymtds[i], gumstix_flash_partitions, ARRAY_SIZE(gumstix_flash_partitions));
++ } else {
++ printk("Registering %s as whole device\n", gumstix_flash_maps[i].name);
++ add_mtd_device(mymtds[i]);
++ }
++ }
++ return 0;
++}
++
++static void __exit gumstix_flashmap_cleanup(void)
++{
++ int i;
++ for (i = 0; i < 1; i++) {
++ if (!mymtds[i])
++ continue;
++
++ if (nr_parsed_parts[i] || !i)
++ del_mtd_partitions(mymtds[i]);
++ else
++ del_mtd_device(mymtds[i]);
++
++ map_destroy(mymtds[i]);
++ iounmap((void *)gumstix_flash_maps[i].virt);
++ if (gumstix_flash_maps[i].cached)
++ iounmap(gumstix_flash_maps[i].cached);
++
++ if (parsed_parts[i])
++ kfree(parsed_parts[i]);
++ }
++}
++
++module_init(gumstix_flashmap_init);
++module_exit(gumstix_flashmap_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Gumstix, Inc. <gumstix-users@lists.sf.net>");
++MODULE_DESCRIPTION("MTD map driver for the Gumstix Platform");
+Index: linux-2.6.15gum/drivers/mtd/maps/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mtd/maps/Kconfig
++++ linux-2.6.15gum/drivers/mtd/maps/Kconfig
+@@ -208,6 +208,13 @@ config MTD_SBC_GXX
+ More info at
+ <http://www.arcomcontrols.com/products/icp/pc104/processors/SBC_GX1.htm>.
+
++config MTD_GUMSTIX
++ tristate "CFI Flash device mapped on Gumstix"
++ depends on ARCH_GUMSTIX && MTD_CFI_INTELEXT && MTD_PARTITIONS
++ help
++ This provides a driver for the on-board flash of the Gumstix
++ single board computers.
++
+ config MTD_PXA2XX
+ tristate "CFI Flash device mapped on Intel XScale PXA2xx eval board"
+ depends on (ARCH_LUBBOCK || MACH_MAINSTONE) && MTD_CFI_INTELEXT
+Index: linux-2.6.15gum/drivers/mtd/maps/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mtd/maps/Makefile
++++ linux-2.6.15gum/drivers/mtd/maps/Makefile
+@@ -22,6 +22,7 @@ obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom
+ obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
+ obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
+ obj-$(CONFIG_MTD_PXA2XX) += pxa2xx-flash.o
++obj-$(CONFIG_MTD_GUMSTIX) += gumstix-flash.o
+ obj-$(CONFIG_MTD_MBX860) += mbx860.o
+ obj-$(CONFIG_MTD_CEIVA) += ceiva.o
+ obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
diff --git a/recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch b/recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch
new file mode 100644
index 0000000000..e526712091
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch
@@ -0,0 +1,91 @@
+diff -udrp linux-2.6.15/arch/arm/mach-pxa/gumstix.c linux-2.6.15.mine/arch/arm/mach-pxa/gumstix.c
+--- linux-2.6.15/arch/arm/mach-pxa/gumstix.c 2006-04-11 00:29:42.000000000 -0400
++++ linux-2.6.15.mine/arch/arm/mach-pxa/gumstix.c 2006-04-11 00:11:38.000000000 -0400
+@@ -28,19 +28,60 @@
+
+ #include "generic.h"
+
+-static int gumstix_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data)
++static struct pxamci_platform_data gumstix_mci_platform_data;
++
++static int gumstix_mci_init(struct device *dev, irqreturn_t (*gumstix_detect_int)(int, void *, struct pt_regs *), void *data)
+ {
+- // Set up MMC controller
++ int err;
++
++ //printk("entering gumstix_mci_init\n");
++
+ pxa_gpio_mode(GPIO6_MMCCLK_MD);
+ pxa_gpio_mode(GPIO53_MMCCLK_MD);
+ pxa_gpio_mode(GPIO8_MMCCS0_MD);
+
++ //printk(" setting gpio sd detect\n");
++ pxa_gpio_mode(GUMSTIX_GPIO_nSD_DETECT | GPIO_IN);
++ pxa_gpio_mode(GUMSTIX_GPIO_nSD_WP | GPIO_IN);
++
++ //printk(" setting delay to ");
++ gumstix_mci_platform_data.detect_delay = msecs_to_jiffies(200);
++ //printk("%d\n", gumstix_mci_platform_data.detect_delay);
++
++ err = request_irq(GUMSTIX_IRQ_GPIO_nSD_DETECT, gumstix_detect_int, SA_INTERRUPT,
++ "MMC card detect", data);
++ if (err) {
++ printk(KERN_ERR "gumstix_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
++ return -1;
++ }
++
++ //printk(" set_irq_type returned a ");
++ err = set_irq_type(GUMSTIX_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
++ //printk("%d\n", err);
++
+ return 0;
+ }
+
++static int gumstix_mci_get_ro(struct device *dev)
++{
++ int ro;
++ //printk("entering gumstix_mci_get_ro\n");
++ ro = GPLR(GUMSTIX_GPIO_nSD_WP) & GPIO_bit(GUMSTIX_GPIO_nSD_WP);
++ //printk(" ro is %d\n", ro);
++ return ro;
++}
++
++static void gumstix_mci_exit(struct device *dev, void *data)
++{
++ //printk("entering gumstix_mci_exit\n");
++ free_irq(GUMSTIX_IRQ_GPIO_nSD_DETECT, data);
++}
++
+ static struct pxamci_platform_data gumstix_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+- .init = &gumstix_mci_init,
++ .init = gumstix_mci_init,
++ .get_ro = gumstix_mci_get_ro,
++ .exit = gumstix_mci_exit,
+ };
+
+ static int gumstix_udc_is_connected(void)
+@@ -76,6 +117,7 @@ static struct platform_device *devices[]
+
+ static void __init gumstix_init(void)
+ {
++ //printk("entering gumstix_init\n");
+ pxa_set_mci_info(&gumstix_mci_platform_data);
+ pxa_set_udc_info(&gumstix_udc_info);
+ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+diff -udrp linux-2.6.15/include/asm-arm/arch-pxa/gumstix.h linux-2.6.15.mine/include/asm-arm/arch-pxa/gumstix.h
+--- linux-2.6.15/include/asm-arm/arch-pxa/gumstix.h 2006-04-11 00:29:43.000000000 -0400
++++ linux-2.6.15.mine/include/asm-arm/arch-pxa/gumstix.h 2006-04-10 22:26:20.000000000 -0400
+@@ -36,6 +36,12 @@
+ #define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
+ #define GPIO_GUMSTIX_USB_GPIOx_DIS_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN)
+
++/*
++ * SD/MMC definitions
++ */
++#define GUMSTIX_GPIO_nSD_WP (22) /* SD Write Protect? */
++#define GUMSTIX_GPIO_nSD_DETECT (11) /* MMC/SD Card Detect */
++#define GUMSTIX_IRQ_GPIO_nSD_DETECT IRQ_GPIO(11)
+
+ /*
+ * SMC Ethernet definitions
diff --git a/recipes/linux/linux-gumstix-2.6.15/header.patch b/recipes/linux/linux-gumstix-2.6.15/header.patch
new file mode 100644
index 0000000000..51cfa08cc6
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/header.patch
@@ -0,0 +1,87 @@
+Index: linux-2.6.15gum/include/asm-arm/arch-pxa/gumstix.h
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/include/asm-arm/arch-pxa/gumstix.h
+@@ -0,0 +1,82 @@
++/*
++ * linux/include/asm-arm/arch-pxa/gumstix.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.
++ */
++
++
++/* BTRESET - Reset line to Bluetooth module, active low signal. */
++#define GPIO_GUMSTIX_BTRESET 7
++#define GPIO_GUMSTIX_BTRESET_MD (GPIO_GUMSTIX_BTRESET | GPIO_OUT)
++
++
++/* GPIOn - Input from MAX823 (or equiv), normalizing USB +5V
++ into a clean interrupt signal for determining cable presence
++ On the original gumstix, this is GPIO81, and GPIO83 needs to be defined as well.
++ On the gumstix F, this moves to GPIO17 and GPIO37 */
++/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn
++ has detected a cable insertion; driven low otherwise. */
++
++#ifdef CONFIG_ARCH_GUMSTIX_ORIG
++
++#define GPIO_GUMSTIX_USB_GPIOn 81
++#define GPIO_GUMSTIX_USB_GPIOx 83
++
++#else
++
++#define GPIO_GUMSTIX_USB_GPIOn 35
++#define GPIO_GUMSTIX_USB_GPIOx 41
++
++#endif
++
++#define GUMSTIX_USB_INTR_IRQ IRQ_GPIO(GPIO_GUMSTIX_USB_GPIOn) /* usb state change */
++#define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN)
++#define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
++#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN)
++
++
++/*
++ * SMC Ethernet definitions
++ * ETH_RST provides a hardware reset line to the ethernet chip
++ * ETH is the IRQ line in from the ethernet chip to the PXA
++ */
++#define GPIO_GUMSTIX_ETH0_RST 80
++#define GPIO_GUMSTIX_ETH0_RST_MD (GPIO_GUMSTIX_ETH0_RST | GPIO_OUT)
++#define GPIO_GUMSTIX_ETH1_RST 52
++#define GPIO_GUMSTIX_ETH1_RST_MD (GPIO_GUMSTIX_ETH1_RST | GPIO_OUT)
++
++#define GPIO_GUMSTIX_ETH0 36
++#define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN)
++#define GUMSTIX_ETH0_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH0)
++#define GPIO_GUMSTIX_ETH1 27
++#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN)
++#define GUMSTIX_ETH1_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH1)
++
++
++/*
++ * The following are missing from pxa-regs.h
++ */
++
++#define GPIO4_nBVD1 4
++#define GPIO4_nSTSCHG GPIO4_nBVD1
++#define GPIO8_RESET 8
++#define GPIO11_nPCD1 11
++#define GPIO22_nINPACK 22
++#define GPIO26_PRDY_nBSY0 26
++#define GPIO36_nBVD2 36
++
++#define GPIO4_nBVD1_MD ( GPIO4_nBVD1| GPIO_IN )
++#define GPIO4_nSTSCHG_MD ( GPIO4_nSTSCHG | GPIO_IN )
++#define GPIO8_RESET_MD ( GPIO8_RESET | GPIO_OUT )
++#define GPIO11_nPCD1_MD ( GPIO11_nPCD1 | GPIO_IN )
++#define GPIO22_nINPACK_MD ( GPIO22_nINPACK | GPIO_IN )
++#define GPIO26_PRDY_nBSY0_MD ( GPIO26_PRDY_nBSY0 | GPIO_IN )
++#define GPIO36_nBVD2_MD ( GPIO36_nBVD2 | GPIO_IN )
++
++#define GUMSTIX_nSTSCHG_IRQ IRQ_GPIO(GPIO4_nSTSCHG)
++#define GUMSTIX_nPCD1_IRQ IRQ_GPIO(GPIO11_nPCD1)
++#define GUSMTIX_nBVD1_IRQ IRQ_GPIO(GPIO4_nBVD1)
++#define GUMSTIX_nBVD2_IRQ IRQ_GPIO(GPIO36_nBVD2)
++#define GUMSTIX_PRDY_nBSY0_IRQ IRQ_GPIO(GPIO26_PRDY_nBSY0)
diff --git a/recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch b/recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch
new file mode 100644
index 0000000000..408bb1854d
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch
@@ -0,0 +1,43 @@
+Index: linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/i2c/busses/i2c-pxa.c
++++ linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c
+@@ -32,7 +32,6 @@
+ #include <linux/i2c-pxa.h>
+ #include <linux/platform_device.h>
+
+-#include <asm/arch/pxa-regs.h>
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/arch/i2c.h>
+@@ -900,6 +899,12 @@ static int i2c_pxa_xfer(struct i2c_adapt
+ struct pxa_i2c *i2c = adap->algo_data;
+ int ret, i;
+
++ /* If the I2C controller is disabled we need to reset it (probably due
++ to a suspend/resume destroying state). We do this here as we can then
++ avoid worrying about resuming the controller before its users. */
++ if (!(ICR & ICR_IUE))
++ i2c_pxa_reset(i2c);
++
+ for (i = adap->retries; i >= 0; i--) {
+ ret = i2c_pxa_do_xfer(i2c, msgs, num);
+ if (ret != I2C_RETRY)
+@@ -940,7 +945,9 @@ static struct pxa_i2c i2c_pxa = {
+ static int i2c_pxa_probe(struct platform_device *dev)
+ {
+ struct pxa_i2c *i2c = &i2c_pxa;
++#ifdef CONFIG_I2C_PXA_SLAVE
+ struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
++#endif
+ int ret;
+
+ #ifdef CONFIG_PXA27x
+@@ -1025,5 +1032,7 @@ static void i2c_adap_pxa_exit(void)
+ return platform_driver_unregister(&i2c_pxa_driver);
+ }
+
++MODULE_LICENSE("GPL");
++
+ module_init(i2c_adap_pxa_init);
+ module_exit(i2c_adap_pxa_exit);
diff --git a/recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch b/recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch
new file mode 100644
index 0000000000..1d35bfa805
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch
@@ -0,0 +1,72 @@
+Index: linux-2.6.15gum/arch/arm/mach-clps711x/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-clps711x/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-clps711x/Kconfig
+@@ -1,6 +1,7 @@
+ if ARCH_CLPS711X
+
+ menu "CLPS711X/EP721X Implementations"
++ depends on ARCH_CLPS711X
+
+ config ARCH_AUTCPU12
+ bool "AUTCPU12"
+Index: linux-2.6.15gum/arch/arm/mach-epxa10db/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-epxa10db/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-epxa10db/Kconfig
+@@ -1,6 +1,7 @@
+ if ARCH_CAMELOT
+
+ menu "Epxa10db"
++ depends on ARCH_CAMELOT
+
+ comment "PLD hotswap support"
+
+Index: linux-2.6.15gum/arch/arm/mach-footbridge/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-footbridge/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-footbridge/Kconfig
+@@ -1,6 +1,7 @@
+ if ARCH_FOOTBRIDGE
+
+ menu "Footbridge Implementations"
++ depends on ARCH_FOOTBRIDGE
+
+ config ARCH_CATS
+ bool "CATS"
+Index: linux-2.6.15gum/arch/arm/mach-iop3xx/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-iop3xx/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-iop3xx/Kconfig
+@@ -1,6 +1,7 @@
+ if ARCH_IOP3XX
+
+ menu "IOP3xx Implementation Options"
++ depends on ARCH_IOP3XX
+
+ comment "IOP3xx Platform Types"
+
+Index: linux-2.6.15gum/arch/arm/mach-lh7a40x/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-lh7a40x/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-lh7a40x/Kconfig
+@@ -1,6 +1,7 @@
+ if ARCH_LH7A40X
+
+ menu "LH7A40X Implementations"
++ depends on ARCH_LH7A40X
+
+ config MACH_KEV7A400
+ bool "KEV7A400"
+Index: linux-2.6.15gum/arch/arm/mach-sa1100/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-sa1100/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-sa1100/Kconfig
+@@ -1,6 +1,7 @@
+ if ARCH_SA1100
+
+ menu "SA11x0 Implementations"
++ depends on ARCH_SA1100
+
+ config SA1100_ASSABET
+ bool "Assabet"
diff --git a/recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch b/recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch
new file mode 100644
index 0000000000..b50001db57
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch
@@ -0,0 +1,50 @@
+Index: linux-2.6.15gum/scripts/Makefile.host
+===================================================================
+--- linux-2.6.15gum.orig/scripts/Makefile.host
++++ linux-2.6.15gum/scripts/Makefile.host
+@@ -137,15 +137,17 @@ $(host-cxxobjs): %.o: %.cc FORCE
+
+ # Compile .c file, create position independent .o file
+ # host-cshobjs -> .o
+-quiet_cmd_host-cshobjs = HOSTCC -fPIC $@
+- cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
++quiet_cmd_host-cshobjs = HOSTCC -fPIC -fno-common $@
++ cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -fno-common -c -o $@ $<
+ $(host-cshobjs): %.o: %.c FORCE
+ $(call if_changed_dep,host-cshobjs)
+
+ # Link a shared library, based on position independent .o files
+ # *.o -> .so shared library (host-cshlib)
+-quiet_cmd_host-cshlib = HOSTLLD -shared $@
+- cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
++SHARED_SWITCH = `if $(HOSTCC) -dM -E - < /dev/null | grep -q APPLE; \
++ then echo "-dynamiclib"; else echo "-shared"; fi`
++quiet_cmd_host-cshlib = HOSTLLD $(SHARED_SWITCH) $@
++ cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) $(SHARED_SWITCH) -o $@ \
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+ $(host-cshlib): %: $(host-cshobjs) FORCE
+Index: linux-2.6.15gum/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/Makefile
++++ linux-2.6.15gum/Makefile
+@@ -203,7 +203,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
+
+ HOSTCC = gcc
+ HOSTCXX = g++
+-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -idirafter "`$(CC) -print-file-name=include`/../../../../../include/"
++
+ HOSTCXXFLAGS = -O2
+
+ # Decide whether to build built-in, modular, or both.
+Index: linux-2.6.15gum/scripts/mod/sumversion.c
+===================================================================
+--- linux-2.6.15gum.orig/scripts/mod/sumversion.c
++++ linux-2.6.15gum/scripts/mod/sumversion.c
+@@ -1,4 +1,4 @@
+-#include <netinet/in.h>
++#include <arpa/inet.h>
+ #ifdef __sun__
+ #include <inttypes.h>
+ #else
diff --git a/recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch b/recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch
new file mode 100644
index 0000000000..e54351155a
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch
@@ -0,0 +1,13 @@
+Oddly, devices/input/input.c seems to reference a symbol which is in another module but is not exported.
+Index: linux-2.6.15gum/lib/kobject.c
+===================================================================
+--- linux-2.6.15gum.orig/lib/kobject.c
++++ linux-2.6.15gum/lib/kobject.c
+@@ -115,6 +115,7 @@ char *kobject_get_path(struct kobject *k
+
+ return path;
+ }
++EXPORT_SYMBOL(kobject_get_path);
+
+ /**
+ * kobject_init - initialize object.
diff --git a/recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch b/recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch
new file mode 100644
index 0000000000..a74edf0bf6
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch
@@ -0,0 +1,13 @@
+Index: linux-2.6.15gum/arch/arm/tools/mach-types
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/tools/mach-types
++++ linux-2.6.15gum/arch/arm/tools/mach-types
+@@ -387,7 +387,7 @@ s5c7375 ARCH_S5C7375 S5C7375 369
+ spearhead ARCH_SPEARHEAD SPEARHEAD 370
+ pantera ARCH_PANTERA PANTERA 371
+ prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372
+-gumstix ARCH_GUMSTIK GUMSTIK 373
++gumstix ARCH_GUMSTIX GUMSTIX 373
+ rcube ARCH_RCUBE RCUBE 374
+ rea_olv ARCH_REA_OLV REA_OLV 375
+ pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376
diff --git a/recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch b/recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch
new file mode 100644
index 0000000000..c572dbcc2a
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch
@@ -0,0 +1,12 @@
+Index: linux-2.6.15gum/drivers/mmc/mmc.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mmc/mmc.c
++++ linux-2.6.15gum/drivers/mmc/mmc.c
+@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_ca
+
+ case 2: /* MMC v2.0 - v2.2 */
+ case 3: /* MMC v3.1 - v3.3 */
++ case 4: /* MMC v4.x */
+ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
+ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
+ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
diff --git a/recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch b/recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch
new file mode 100644
index 0000000000..c5d96f87d9
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch
@@ -0,0 +1,106 @@
+Index: linux-2.6.15gum/net/bluetooth/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/net/bluetooth/Kconfig
++++ linux-2.6.15gum/net/bluetooth/Kconfig
+@@ -30,6 +30,12 @@ menuconfig BT
+ Bluetooth kernel modules are provided in the BlueZ packages.
+ For more information, see <http://www.bluez.org/>.
+
++config BT_GUMSTIX
++ tristate
++ default m if BT=m
++ default y if BT=y
++ depends on BT && ARCH_GUMSTIX
++
+ config BT_L2CAP
+ tristate "L2CAP protocol support"
+ depends on BT
+Index: linux-2.6.15gum/net/bluetooth/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/net/bluetooth/Makefile
++++ linux-2.6.15gum/net/bluetooth/Makefile
+@@ -9,5 +9,6 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm/
+ obj-$(CONFIG_BT_BNEP) += bnep/
+ obj-$(CONFIG_BT_CMTP) += cmtp/
+ obj-$(CONFIG_BT_HIDP) += hidp/
++obj-$(CONFIG_BT_GUMSTIX)+= gumstix_bluetooth.o
+
+ bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
+Index: linux-2.6.15gum/net/bluetooth/af_bluetooth.c
+===================================================================
+--- linux-2.6.15gum.orig/net/bluetooth/af_bluetooth.c
++++ linux-2.6.15gum/net/bluetooth/af_bluetooth.c
+@@ -304,10 +304,18 @@ static struct net_proto_family bt_sock_f
+ .create = bt_sock_create,
+ };
+
++#ifdef CONFIG_ARCH_GUMSTIX
++extern void gumstix_bluetooth_load(void);
++#endif
++
+ static int __init bt_init(void)
+ {
+ BT_INFO("Core ver %s", VERSION);
+
++#ifdef CONFIG_ARCH_GUMSTIX
++ gumstix_bluetooth_load();
++#endif
++
+ sock_register(&bt_sock_family_ops);
+
+ BT_INFO("HCI device and connection manager initialized");
+Index: linux-2.6.15gum/net/bluetooth/gumstix_bluetooth.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/net/bluetooth/gumstix_bluetooth.c
+@@ -0,0 +1,50 @@
++/*
++ * Gumstix bluetooth module intialization driver
++ *
++ * Author: Craig Hughes
++ * Created: December 9, 2004
++ * Copyright: (C) 2004 Craig Hughes
++ *
++ * 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.
++ *
++ */
++
++#include <linux/module.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/delay.h>
++
++#include <asm/arch/gumstix.h>
++
++static void gumstix_bluetooth_load(void)
++{
++}
++
++EXPORT_SYMBOL(gumstix_bluetooth_load);
++
++int __init gumstix_bluetooth_init(void)
++{
++ /* Set up GPIOs to use the BTUART */
++ pxa_gpio_mode(GPIO42_HWRXD_MD);
++ pxa_gpio_mode(GPIO43_HWTXD_MD);
++ pxa_gpio_mode(GPIO44_HWCTS_MD);
++ pxa_gpio_mode(GPIO45_HWRTS_MD);
++
++ return 0;
++}
++
++void __exit gumstix_bluetooth_exit(void)
++{
++}
++
++module_init(gumstix_bluetooth_init);
++module_exit(gumstix_bluetooth_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Craig Hughes <craig@gumstix.com>");
++MODULE_DESCRIPTION("Gumstix board bluetooth module initialization driver");
++MODULE_VERSION("1:0.1");
diff --git a/recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch b/recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch
new file mode 100644
index 0000000000..15a2bc06be
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch
@@ -0,0 +1,171 @@
+Index: linux-2.6.15gum/drivers/net/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/net/Kconfig
++++ linux-2.6.15gum/drivers/net/Kconfig
+@@ -826,6 +826,12 @@ config SMC91X
+ module, say M here and read <file:Documentation/modules.txt> as well
+ as <file:Documentation/networking/net-modules.txt>.
+
++config SMC91X_GUMSTIX
++ tristate
++ default m if SMC91X=m
++ default y if SMC91X=y
++ depends on SMC91X && ARCH_GUMSTIX
++
+ config SMC9194
+ tristate "SMC 9194 support"
+ depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
+Index: linux-2.6.15gum/drivers/net/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/net/Makefile
++++ linux-2.6.15gum/drivers/net/Makefile
+@@ -191,6 +191,7 @@ obj-$(CONFIG_SMC91X) += smc91x.o
+ obj-$(CONFIG_DM9000) += dm9000.o
+ obj-$(CONFIG_FEC_8XX) += fec_8xx/
+
++obj-$(CONFIG_SMC91X_GUMSTIX) += gumstix-smc91x.o
+ obj-$(CONFIG_ARM) += arm/
+ obj-$(CONFIG_DEV_APPLETALK) += appletalk/
+ obj-$(CONFIG_TR) += tokenring/
+Index: linux-2.6.15gum/drivers/net/smc91x.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/net/smc91x.c
++++ linux-2.6.15gum/drivers/net/smc91x.c
+@@ -2366,6 +2366,10 @@ static struct platform_driver smc_driver
+ },
+ };
+
++#ifdef CONFIG_ARCH_GUMSTIX
++extern void gumstix_smc91x_load(void);
++#endif
++
+ static int __init smc_init(void)
+ {
+ #ifdef MODULE
+@@ -2377,6 +2381,10 @@ static int __init smc_init(void)
+ #endif
+ #endif
+
++#ifdef CONFIG_ARCH_GUMSTIX
++ gumstix_smc91x_load();
++#endif
++
+ return platform_driver_register(&smc_driver);
+ }
+
+Index: linux-2.6.15gum/drivers/net/gumstix-smc91x.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/net/gumstix-smc91x.c
+@@ -0,0 +1,111 @@
++/*
++ * Gumstix SMC91C111 chip intialization driver
++ *
++ * Author: Craig Hughes
++ * Created: December 9, 2004
++ * Copyright: (C) 2004 Craig Hughes
++ *
++ * 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.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/ioport.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/delay.h>
++
++#include <asm/arch/gumstix.h>
++
++static struct resource gumstix_smc91x0_resources[] = {
++ [0] = {
++ .name = "smc91x-regs",
++ .start = PXA_CS1_PHYS + 0x00000300,
++ .end = PXA_CS1_PHYS + 0x000fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = GUMSTIX_ETH0_IRQ,
++ .end = GUMSTIX_ETH0_IRQ,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct resource gumstix_smc91x1_resources[] = {
++ [0] = {
++ .name = "smc91x-regs",
++ .start = PXA_CS2_PHYS + 0x00000300,
++ .end = PXA_CS2_PHYS + 0x000fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = GUMSTIX_ETH1_IRQ,
++ .end = GUMSTIX_ETH1_IRQ,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device gumstix_smc91x0_device = {
++ .name = "smc91x",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(gumstix_smc91x0_resources),
++ .resource = gumstix_smc91x0_resources,
++};
++
++static struct platform_device gumstix_smc91x1_device = {
++ .name = "smc91x",
++ .id = 1,
++ .num_resources = ARRAY_SIZE(gumstix_smc91x1_resources),
++ .resource = gumstix_smc91x1_resources,
++};
++
++static struct platform_device *smc91x_devices[] __initdata = {
++ &gumstix_smc91x0_device,
++ &gumstix_smc91x1_device,
++};
++
++int __init gumstix_smc91x_init(void)
++{
++ /* Set up nPWE */
++ pxa_gpio_mode(GPIO49_nPWE_MD);
++
++ /* Set up the chip selects */
++ pxa_gpio_mode(GPIO15_nCS_1_MD);
++ pxa_gpio_mode(GPIO78_nCS_2_MD);
++
++ /* Reset the SMC91c111(s) */
++ pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD);
++ pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD);
++ GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
++ GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
++ udelay(1); // Hold RESET pin high for at least 100ns
++ GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
++ GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
++ msleep(50);
++
++ return platform_add_devices(smc91x_devices, ARRAY_SIZE(smc91x_devices));
++}
++
++void __exit gumstix_smc91x_exit(void)
++{
++ platform_device_unregister(&gumstix_smc91x1_device);
++ platform_device_unregister(&gumstix_smc91x0_device);
++}
++
++void gumstix_smc91x_load(void) {}
++EXPORT_SYMBOL(gumstix_smc91x_load);
++
++module_init(gumstix_smc91x_init);
++module_exit(gumstix_smc91x_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Craig Hughes <craig@gumstix.com>");
++MODULE_DESCRIPTION("Gumstix board SMC91C111 chip initialization driver");
++MODULE_VERSION("1:0.1");
diff --git a/recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch b/recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch
new file mode 100644
index 0000000000..94666ff812
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch
@@ -0,0 +1,105 @@
+Index: linux-2.6.15gum/drivers/usb/gadget/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/usb/gadget/Kconfig
++++ linux-2.6.15gum/drivers/usb/gadget/Kconfig
+@@ -56,6 +56,14 @@ config USB_GADGET_DEBUG_FILES
+ config USB_GADGET_SELECTED
+ boolean
+
++config USB_GADGET_GUMSTIX
++ tristate
++ default m if USB_GADGET=m
++ default y if USB_GADGET=y
++ depends on USB_GADGET && ARCH_GUMSTIX
++ help
++ USB Gadget support for the Gumstix platform
++
+ #
+ # USB Peripheral Controller Support
+ #
+Index: linux-2.6.15gum/drivers/usb/gadget/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/usb/gadget/Makefile
++++ linux-2.6.15gum/drivers/usb/gadget/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o
+ obj-$(CONFIG_USB_GOKU) += goku_udc.o
+ obj-$(CONFIG_USB_OMAP) += omap_udc.o
+ obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
++obj-$(CONFIG_USB_GADGET_GUMSTIX) += gumstix_gadget.o
+
+ #
+ # USB gadget drivers
+Index: linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/usb/gadget/pxa2xx_udc.c
++++ linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c
+@@ -2679,8 +2679,16 @@ static struct platform_driver udc_driver
+ },
+ };
+
++#ifdef CONFIG_ARCH_GUMSTIX
++extern void gumstix_usb_gadget_load(void);
++#endif
++
+ static int __init udc_init(void)
+ {
++#ifdef CONFIG_ARCH_GUMSTIX
++ gumstix_usb_gadget_load();
++#endif
++
+ printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
+ return platform_driver_register(&udc_driver);
+ }
+Index: linux-2.6.15gum/drivers/usb/gadget/gumstix_gadget.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/usb/gadget/gumstix_gadget.c
+@@ -0,0 +1,48 @@
++/*
++ * Gumstix USB gadget intialization driver
++ *
++ * Author: Craig Hughes
++ * Created: December 9, 2004
++ * Copyright: (C) 2004 Craig Hughes
++ *
++ * 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.
++ *
++ */
++
++#include <linux/module.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/delay.h>
++#include <asm/irq.h>
++
++#include <asm/arch/gumstix.h>
++#include <asm/arch/udc.h>
++
++int __init gumstix_usb_gadget_init(void)
++{
++ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOx_DIS_MD);
++ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOn_MD);
++
++ set_irq_type(GUMSTIX_USB_INTR_IRQ, IRQT_BOTHEDGE);
++
++ return 0;
++}
++
++void __exit gumstix_usb_gadget_exit(void)
++{
++}
++
++void gumstix_usb_gadget_load(void) {}
++EXPORT_SYMBOL(gumstix_usb_gadget_load);
++
++module_init(gumstix_usb_gadget_init);
++module_exit(gumstix_usb_gadget_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Craig Hughes <craig@gumstix.com>");
++MODULE_DESCRIPTION("Gumstix board USB gadget initialization driver");
++MODULE_VERSION("1:0.1");
diff --git a/recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch b/recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch
new file mode 100644
index 0000000000..1a53d1b1d0
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch
@@ -0,0 +1,401 @@
+Index: linux-2.6.15gum/arch/arm/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/Kconfig
++++ linux-2.6.15gum/arch/arm/Kconfig
+@@ -316,6 +316,8 @@ config PCI_HOST_VIA82C505
+ depends on PCI && ARCH_SHARK
+ default y
+
++source "drivers/gpio/Kconfig"
++
+ source "drivers/pci/Kconfig"
+
+ source "drivers/pcmcia/Kconfig"
+Index: linux-2.6.15gum/drivers/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/Makefile
++++ linux-2.6.15gum/drivers/Makefile
+@@ -70,3 +70,4 @@ obj-$(CONFIG_SGI_IOC4) += sn/
+ obj-y += firmware/
+ obj-$(CONFIG_CRYPTO) += crypto/
+ obj-$(CONFIG_SUPERH) += sh/
++obj-$(CONFIG_PROC_GPIO) += gpio/
+Index: linux-2.6.15gum/drivers/gpio/Kconfig
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/gpio/Kconfig
+@@ -0,0 +1,6 @@
++config PROC_GPIO
++ tristate "GPIO /proc interface"
++ depends on PXA25x
++ help
++ This enables an interface under /proc/gpio which allows reading or setting
++ of any GPIO. Currently only reading is supported.
+Index: linux-2.6.15gum/drivers/gpio/Makefile
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/gpio/Makefile
+@@ -0,0 +1,3 @@
++# Expose GPIOs under /proc
++obj-$(CONFIG_PROC_GPIO) += proc_gpio.o
++
+Index: linux-2.6.15gum/drivers/gpio/proc_gpio.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/gpio/proc_gpio.c
+@@ -0,0 +1,355 @@
++/*
++ *
++ * PXA25x GPIOs exposed under /proc for reading and writing
++ * They will show up under /proc/gpio/NN
++ *
++ * Based on patch 1773/1 in the arm kernel patch repository at arm.linux.co.uk
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/string.h>
++#include <linux/ctype.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/uaccess.h>
++
++static struct proc_dir_entry *proc_gpio_parent;
++static struct proc_dir_entry *proc_gpios[85];
++
++typedef struct
++{
++ int gpio;
++ char name[32];
++} gpio_summary_type;
++
++static gpio_summary_type gpio_summaries[85] =
++{
++ { 0, "GPIO0" },
++ { 1, "GPIO1" },
++ { 2, "GPIO2" },
++ { 3, "GPIO3" },
++ { 4, "GPIO4" },
++ { 5, "GPIO5" },
++ { 6, "GPIO6" },
++ { 7, "GPIO7" },
++ { 8, "GPIO8" },
++ { 9, "GPIO9" },
++ { 10, "GPIO10" },
++ { 11, "GPIO11" },
++ { 12, "GPIO12" },
++ { 13, "GPIO13" },
++ { 14, "GPIO14" },
++ { 15, "GPIO15" },
++ { 16, "GPIO16" },
++ { 17, "GPIO17" },
++ { 18, "GPIO18" },
++ { 19, "GPIO19" },
++ { 20, "GPIO20" },
++ { 21, "GPIO21" },
++ { 22, "GPIO22" },
++ { 23, "GPIO23" },
++ { 24, "GPIO24" },
++ { 25, "GPIO25" },
++ { 26, "GPIO26" },
++ { 27, "GPIO27" },
++ { 28, "GPIO28" },
++ { 29, "GPIO29" },
++ { 30, "GPIO30" },
++ { 31, "GPIO31" },
++ { 32, "GPIO32" },
++ { 33, "GPIO33" },
++ { 34, "GPIO34" },
++ { 35, "GPIO35" },
++ { 36, "GPIO36" },
++ { 37, "GPIO37" },
++ { 38, "GPIO38" },
++ { 39, "GPIO39" },
++ { 40, "GPIO40" },
++ { 41, "GPIO41" },
++ { 42, "GPIO42" },
++ { 43, "GPIO43" },
++ { 44, "GPIO44" },
++ { 45, "GPIO45" },
++ { 46, "GPIO46" },
++ { 47, "GPIO47" },
++ { 48, "GPIO48" },
++ { 49, "GPIO49" },
++ { 50, "GPIO50" },
++ { 51, "GPIO51" },
++ { 52, "GPIO52" },
++ { 53, "GPIO53" },
++ { 54, "GPIO54" },
++ { 55, "GPIO55" },
++ { 56, "GPIO56" },
++ { 57, "GPIO57" },
++ { 58, "GPIO58" },
++ { 59, "GPIO59" },
++ { 60, "GPIO60" },
++ { 61, "GPIO61" },
++ { 62, "GPIO62" },
++ { 63, "GPIO63" },
++ { 64, "GPIO64" },
++ { 65, "GPIO65" },
++ { 66, "GPIO66" },
++ { 67, "GPIO67" },
++ { 68, "GPIO68" },
++ { 69, "GPIO69" },
++ { 70, "GPIO70" },
++ { 71, "GPIO71" },
++ { 72, "GPIO72" },
++ { 73, "GPIO73" },
++ { 74, "GPIO74" },
++ { 75, "GPIO75" },
++ { 76, "GPIO76" },
++ { 77, "GPIO77" },
++ { 78, "GPIO78" },
++ { 79, "GPIO79" },
++ { 80, "GPIO80" },
++ { 81, "GPIO81" },
++ { 82, "GPIO82" },
++ { 83, "GPIO83" },
++ { 84, "GPIO84" },
++};
++
++static int proc_gpio_write(struct file *file, const char __user *buf,
++ unsigned long count, void *data)
++{
++ char *cur, lbuf[count + 1];
++ gpio_summary_type *summary = data;
++ u32 altfn, direction, setclear, gafr;
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ memset(lbuf, 0, count + 1);
++
++ if (copy_from_user(lbuf, buf, count))
++ return -EFAULT;
++
++ cur = lbuf;
++
++ // Initialize to current state
++ altfn = ((GAFR(summary->gpio) >> ((summary->gpio & 0x0f) << 0x01)) & 0x03);
++ direction = GPDR(summary->gpio) & GPIO_bit(summary->gpio);
++ setclear = GPLR(summary->gpio) & GPIO_bit(summary->gpio);
++ while(1)
++ {
++ // We accept options: {GPIO|AF1|AF2|AF3}, {set|clear}, {in|out}
++ // Anything else is an error
++ while(cur[0] && (isspace(cur[0]) || ispunct(cur[0]))) cur = &(cur[1]);
++
++ if('\0' == cur[0]) break;
++
++ // Ok, so now we're pointing at the start of something
++ switch(cur[0])
++ {
++ case 'G':
++ // Check that next is "PIO" -- '\0' will cause safe short-circuit if end of buf
++ if(!(cur[1] == 'P' && cur[2] == 'I' && cur[3] == 'O')) goto parse_error;
++ // Ok, so set this GPIO to GPIO (non-ALT) function
++ altfn = 0;
++ cur = &(cur[4]);
++ break;
++ case 'A':
++ if(!(cur[1] == 'F' && cur[2] >= '1' && cur[2] <= '3')) goto parse_error;
++ altfn = cur[2] - '0';
++ cur = &(cur[3]);
++ break;
++ case 's':
++ if(!(cur[1] == 'e' && cur[2] == 't')) goto parse_error;
++ setclear = 1;
++ cur = &(cur[3]);
++ break;
++ case 'c':
++ if(!(cur[1] == 'l' && cur[2] == 'e' && cur[3] == 'a' && cur[4] == 'r')) goto parse_error;
++ setclear = 0;
++ cur = &(cur[5]);
++ break;
++ case 'i':
++ if(!(cur[1] == 'n')) goto parse_error;
++ direction = 0;
++ cur = &(cur[2]);
++ break;
++ case 'o':
++ if(!(cur[1] == 'u' && cur[2] == 't')) goto parse_error;
++ direction = 1;
++ cur = &(cur[3]);
++ break;
++ default: goto parse_error;
++ }
++ }
++ // Ok, now set gpio mode and value
++ if(direction)
++ GPDR(summary->gpio) |= GPIO_bit(summary->gpio);
++ else
++ GPDR(summary->gpio) &= ~GPIO_bit(summary->gpio);
++
++ gafr = GAFR(summary->gpio) & ~(0x3 << (((summary->gpio) & 0xf)*2));
++ GAFR(summary->gpio) = gafr | (altfn << (((summary->gpio) & 0xf)*2));
++
++ if(direction && !altfn)
++ {
++ if(setclear) GPSR(summary->gpio) = GPIO_bit(summary->gpio);
++ else GPCR(summary->gpio) = GPIO_bit(summary->gpio);
++ }
++
++ printk(KERN_INFO "Set (%s,%s,%s) via /proc/gpio/%s\n",altfn ? (altfn == 1 ? "AF1" : (altfn == 2 ? "AF2" : "AF3")) : "GPIO",
++ direction ? "out" : "in",
++ setclear ? "set" : "clear",
++ summary->name);
++
++ return count;
++
++parse_error:
++ printk(KERN_CRIT "Parse error: Expect \"[GPIO|AF1|AF2|AF3]|[set|clear]|[in|out] ...\"\n");
++ return -EINVAL;
++}
++
++static int proc_gpio_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ char *p = page;
++ gpio_summary_type *summary = data;
++ int len, i, af;
++ i = summary->gpio;
++
++ p += sprintf(p, "%d\t%s\t%s\t%s\n", i,
++ (af = ((GAFR(i) >> ((i & 0x0f) << 0x01)) & 0x03)) ? (af == 1 ? "AF1" : (af == 2 ? "AF2" : "AF3")) : "GPIO",
++ (GPDR(i) & GPIO_bit(i)) ? "out" : "in",
++ (GPLR(i) & GPIO_bit(i)) ? "set" : "clear");
++
++ len = (p - page) - off;
++
++ if(len < 0)
++ {
++ len = 0;
++ }
++
++ *eof = (len <= count) ? 1 : 0;
++ *start = page + off;
++
++ return len;
++}
++
++static const char const *GAFR_DESC[] = { "GAFR0_L", "GAFR0_U", "GAFR1_L", "GAFR1_U", "GAFR2_L", "GAFR2_U" };
++
++static int proc_gafr_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ char *p = page;
++ int i, len;
++
++ for(i=0; i<=5; i++)
++ {
++ p += sprintf(p, "%s: %08x\n", GAFR_DESC[i], GAFR(i*16));
++ }
++
++ len = (p - page) - off;
++
++ if(len < 0)
++ {
++ len = 0;
++ }
++
++ *eof = (len <= count) ? 1 : 0;
++ *start = page + off;
++
++ return len;
++}
++
++static int proc_gpdr_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ char *p = page;
++ int i, len;
++
++ for(i=0; i<=2; i++)
++ {
++ p += sprintf(p, "GPDR%d: %08x\n", i, GPDR(i * 32));
++ }
++
++ len = (p - page) - off;
++
++ if(len < 0)
++ {
++ len = 0;
++ }
++
++ *eof = (len <= count) ? 1 : 0;
++ *start = page + off;
++
++ return len;
++}
++
++static int proc_gplr_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ char *p = page;
++ int i, len;
++
++ for(i=0; i<=2; i++)
++ {
++ p += sprintf(p, "GPLR%d: %08x\n", i, GPLR(i * 32));
++ }
++
++ len = (p - page) - off;
++
++ if(len < 0)
++ {
++ len = 0;
++ }
++
++ *eof = (len <= count) ? 1 : 0;
++ *start = page + off;
++
++ return len;
++}
++
++static int __init gpio_init(void)
++{
++ int i;
++
++ proc_gpio_parent = create_proc_entry("gpio", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
++ if(!proc_gpio_parent) return 0;
++
++ for(i=0; i < 85; i++)
++ {
++ proc_gpios[i] = create_proc_entry(gpio_summaries[i].name, 0644, proc_gpio_parent);
++ if(proc_gpios[i])
++ {
++ proc_gpios[i]->data = &gpio_summaries[i];
++ proc_gpios[i]->read_proc = proc_gpio_read;
++ proc_gpios[i]->write_proc = proc_gpio_write;
++ }
++ }
++
++ create_proc_read_entry("GAFR", 0444, proc_gpio_parent, proc_gafr_read, NULL);
++ create_proc_read_entry("GPDR", 0444, proc_gpio_parent, proc_gpdr_read, NULL);
++ create_proc_read_entry("GPLR", 0444, proc_gpio_parent, proc_gplr_read, NULL);
++
++ return 0;
++}
++
++static void gpio_exit(void)
++{
++ int i;
++
++ remove_proc_entry("GAFR", proc_gpio_parent);
++ remove_proc_entry("GPDR", proc_gpio_parent);
++ remove_proc_entry("GPLR", proc_gpio_parent);
++
++ for(i=0; i < 85; i++)
++ {
++ if(proc_gpios[i]) remove_proc_entry(gpio_summaries[i].name, proc_gpio_parent);
++ }
++ if(proc_gpio_parent) remove_proc_entry("gpio", NULL);
++}
++
++module_init(gpio_init);
++module_exit(gpio_exit);
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch b/recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch
new file mode 100644
index 0000000000..655f6c577d
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch
@@ -0,0 +1,13 @@
+Index: linux-2.6.15gum/include/asm-arm/arch-pxa/irqs.h
+===================================================================
+--- linux-2.6.15gum.orig/include/asm-arm/arch-pxa/irqs.h
++++ linux-2.6.15gum/include/asm-arm/arch-pxa/irqs.h
+@@ -74,7 +74,7 @@
+ #define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
+
+ #if defined(CONFIG_PXA25x)
+-#define PXA_LAST_GPIO 80
++#define PXA_LAST_GPIO 84
+ #elif defined(CONFIG_PXA27x)
+ #define PXA_LAST_GPIO 127
+ #endif
diff --git a/recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch b/recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch
new file mode 100644
index 0000000000..1e17679907
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch
@@ -0,0 +1,57 @@
+Index: linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/usb/gadget/pxa2xx_udc.c
++++ linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c
+@@ -101,6 +101,10 @@ static const char ep0name [] = "ep0";
+
+ #endif
+
++#ifdef CONFIG_ARCH_GUMSTIX
++#undef CONFIG_USB_PXA2XX_SMALL
++#endif
++
+ #include "pxa2xx_udc.h"
+
+
+@@ -2494,6 +2498,41 @@ static int __init pxa2xx_udc_probe(struc
+ }
+ #endif
+
++ /* Reset UDCCS register to be able to recover from whatever
++ * state UDC was previously in. */
++ *dev->ep[ 2].reg_udccs = UDCCS_BO_RPC | UDCCS_BO_SST;
++#ifndef CONFIG_USB_PXA2XX_SMALL
++ *dev->ep[ 7].reg_udccs = UDCCS_BO_RPC | UDCCS_BO_SST;
++ *dev->ep[12].reg_udccs = UDCCS_BO_RPC | UDCCS_BO_SST;
++#endif
++
++ *dev->ep[ 1].reg_udccs = UDCCS_BI_TPC | UDCCS_BI_FTF |
++ UDCCS_BI_TUR | UDCCS_BI_SST | UDCCS_BI_TSP;
++#ifndef CONFIG_USB_PXA2XX_SMALL
++ *dev->ep[ 6].reg_udccs = UDCCS_BI_TPC | UDCCS_BI_FTF |
++ UDCCS_BI_TUR | UDCCS_BI_SST | UDCCS_BI_TSP;
++ *dev->ep[11].reg_udccs = UDCCS_BI_TPC | UDCCS_BI_FTF |
++ UDCCS_BI_TUR | UDCCS_BI_SST | UDCCS_BI_TSP;
++
++ *dev->ep[ 3].reg_udccs = UDCCS_II_TPC | UDCCS_II_FTF |
++ UDCCS_II_TUR | UDCCS_II_TSP;
++ *dev->ep[ 8].reg_udccs = UDCCS_II_TPC | UDCCS_II_FTF |
++ UDCCS_II_TUR | UDCCS_II_TSP;
++ *dev->ep[13].reg_udccs = UDCCS_II_TPC | UDCCS_II_FTF |
++ UDCCS_II_TUR | UDCCS_II_TSP;
++
++ *dev->ep[ 4].reg_udccs = UDCCS_IO_RPC | UDCCS_IO_ROF;
++ *dev->ep[ 9].reg_udccs = UDCCS_IO_RPC | UDCCS_IO_ROF;
++ *dev->ep[11].reg_udccs = UDCCS_IO_RPC | UDCCS_IO_ROF;
++
++ *dev->ep[ 5].reg_udccs = UDCCS_INT_TPC | UDCCS_INT_FTF |
++ UDCCS_INT_TUR | UDCCS_INT_SST;
++ *dev->ep[10].reg_udccs = UDCCS_INT_TPC | UDCCS_INT_FTF |
++ UDCCS_INT_TUR | UDCCS_INT_SST;
++ *dev->ep[15].reg_udccs = UDCCS_INT_TPC | UDCCS_INT_FTF |
++ UDCCS_INT_TUR | UDCCS_INT_SST;
++#endif
++
+ /* other non-static parts of init */
+ dev->dev = &pdev->dev;
+ dev->mach = pdev->dev.platform_data;
diff --git a/recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch b/recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch
new file mode 100644
index 0000000000..87f4ebdc38
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch
@@ -0,0 +1,329 @@
+Index: linux-2.6.15gum/drivers/char/sa1100-rtc.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/char/sa1100-rtc.c
+@@ -0,0 +1,297 @@
++/*
++ * Real Time Clock interface for Linux on StrongARM SA1100
++ *
++ * Copyright (c) 2000 Nils Faerber
++ *
++ * Based on rtc.c by Paul Gortmaker
++ * Date/time conversion routines taken from arch/arm/kernel/time.c
++ * by Linus Torvalds and Russel King
++ * and the GNU C Library
++ * ( ... I love the GPL ... just take what you need! ;)
++ *
++ * 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.
++ *
++ * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org>
++ * - added periodic timer capability using OSMR1
++ * - flag compatibility with other RTC chips
++ * - permission checks for ioctls
++ * - major cleanup, partial rewrite
++ *
++ * 0.03 2001-03-07 CIH <cih@coventive.com>
++ * - Modify the bug setups RTC clock.
++ *
++ * 0.02 2001-02-27 Nils Faerber <nils@@kernelconcepts.de>
++ * - removed mktime(), added alarm irq clear
++ *
++ * 0.01 2000-10-01 Nils Faerber <nils@@kernelconcepts.de>
++ * - initial release
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/miscdevice.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/rtc.h>
++
++#ifdef CONFIG_ARCH_PXA
++#include <asm/arch/pxa-regs.h>
++#endif
++
++#include <asm/bitops.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/rtc.h>
++
++#define TIMER_FREQ 3686400
++
++#define RTC_DEF_DIVIDER 32768 - 1
++#define RTC_DEF_TRIM 0
++
++/* Those are the bits from a classic RTC we want to mimic */
++#define RTC_IRQF 0x80 /* any of the following 3 is active */
++#define RTC_PF 0x40
++#define RTC_AF 0x20
++#define RTC_UF 0x10
++
++static unsigned long rtc_freq = 1024;
++static struct rtc_time rtc_alarm = {
++ .tm_year = 0,
++ .tm_mon = 0,
++ .tm_mday = 0,
++ .tm_hour = 0,
++ .tm_mon = 0,
++ .tm_sec = 0,
++};
++
++extern spinlock_t rtc_lock;
++
++static int rtc_update_alarm(struct rtc_time *alrm)
++{
++ struct rtc_time alarm_tm, now_tm;
++ unsigned long now, time;
++ int ret;
++
++ printk("Updating alarm\n");
++ do {
++ now = RCNR;
++ rtc_time_to_tm(now, &now_tm);
++ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
++ ret = rtc_tm_to_time(&alarm_tm, &time);
++ if (ret != 0)
++ break;
++
++ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
++ RTAR = time;
++ } while (now != RCNR);
++ printk("set RTAR to %lx, now is %lx\n", time, now);
++
++ return ret;
++}
++
++static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++ unsigned int rtsr;
++ unsigned long events = 0;
++
++ spin_lock(&rtc_lock);
++
++ rtsr = RTSR;
++ /* clear interrupt sources */
++ RTSR = 0;
++ RTSR = (RTSR_AL|RTSR_HZ) & (rtsr >> 2);
++
++ printk(KERN_CRIT "rtc_interrupt: rtsr = %x\n", rtsr);
++
++ /* clear alarm interrupt if it has occurred */
++ if (rtsr & RTSR_AL) {
++ printk(KERN_CRIT "ALARM INTRRUPT\n");
++ rtsr &= ~RTSR_ALE;
++ }
++ RTSR = rtsr & (RTSR_ALE|RTSR_HZE);
++
++ /* update irq data & counter */
++ if (rtsr & RTSR_AL)
++ events |= (RTC_AF|RTC_IRQF);
++ if (rtsr & RTSR_HZ)
++ events |= (RTC_UF|RTC_IRQF);
++
++ rtc_update(1, events);
++
++ if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
++ rtc_update_alarm(&rtc_alarm);
++
++ spin_unlock(&rtc_lock);
++
++ return IRQ_HANDLED;
++}
++
++
++static int sa1100_rtc_open(void)
++{
++ int ret;
++
++ ret = request_irq(IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
++ if (ret) {
++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
++ goto fail_ui;
++ }
++ ret = request_irq(IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
++ if (ret) {
++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
++ goto fail_ai;
++ }
++ return 0;
++
++ fail_ai:
++ free_irq(IRQ_RTC1Hz, NULL);
++ fail_ui:
++ return ret;
++}
++
++static void sa1100_rtc_release(void)
++{
++ spin_lock_irq (&rtc_lock);
++ RTSR = 0;
++ OIER &= ~OIER_E1;
++ OSSR = OSSR_M1;
++ spin_unlock_irq (&rtc_lock);
++
++ free_irq(IRQ_RTCAlrm, NULL);
++ free_irq(IRQ_RTC1Hz, NULL);
++}
++
++static int sa1100_rtc_ioctl(unsigned int cmd, unsigned long arg)
++{
++ switch (cmd) {
++ case RTC_AIE_OFF:
++ spin_lock_irq(&rtc_lock);
++ RTSR &= ~RTSR_ALE;
++ spin_unlock_irq(&rtc_lock);
++ return 0;
++ case RTC_AIE_ON:
++ spin_lock_irq(&rtc_lock);
++ RTSR |= RTSR_ALE;
++ spin_unlock_irq(&rtc_lock);
++ return 0;
++ case RTC_UIE_OFF:
++ spin_lock_irq(&rtc_lock);
++ RTSR &= ~RTSR_HZE;
++ spin_unlock_irq(&rtc_lock);
++ return 0;
++ case RTC_UIE_ON:
++ spin_lock_irq(&rtc_lock);
++ RTSR |= RTSR_HZE;
++ spin_unlock_irq(&rtc_lock);
++ return 0;
++ }
++ return -EINVAL;
++}
++
++static void sa1100_rtc_read_time(struct rtc_time *tm)
++{
++ rtc_time_to_tm(RCNR, tm);
++}
++
++static int sa1100_rtc_set_time(struct rtc_time *tm)
++{
++ unsigned long time;
++ int ret;
++
++ ret = rtc_tm_to_time(tm, &time);
++ if (ret == 0)
++ RCNR = time;
++ return ret;
++}
++
++static void sa1100_rtc_read_alarm(struct rtc_wkalrm *alrm)
++{
++ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
++ alrm->pending = RTSR & RTSR_AL ? 1 : 0;
++}
++
++static int sa1100_rtc_set_alarm(struct rtc_wkalrm *alrm)
++{
++ int ret;
++
++ printk("sa1100_rtc_set_alarm\n");
++
++ spin_lock_irq(&rtc_lock);
++ ret = rtc_update_alarm(&alrm->time);
++ if (ret == 0) {
++ memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time));
++
++ if (alrm->enabled)
++ enable_irq_wake(IRQ_RTCAlrm);
++ else
++ disable_irq_wake(IRQ_RTCAlrm);
++ }
++ spin_unlock_irq(&rtc_lock);
++
++ return ret;
++}
++
++static int sa1100_rtc_proc(char *buf)
++{
++ char *p = buf;
++
++ p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR);
++ p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" );
++ p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no");
++ p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no");
++ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq);
++
++ return p - buf;
++}
++
++static struct rtc_ops sa1100_rtc_ops = {
++ .owner = THIS_MODULE,
++ .open = sa1100_rtc_open,
++ .release = sa1100_rtc_release,
++ .ioctl = sa1100_rtc_ioctl,
++
++ .read_time = sa1100_rtc_read_time,
++ .set_time = sa1100_rtc_set_time,
++ .read_alarm = sa1100_rtc_read_alarm,
++ .set_alarm = sa1100_rtc_set_alarm,
++ .proc = sa1100_rtc_proc,
++};
++
++static int __init rtc_init(void)
++{
++ /*
++ * According to the manual we should be able to let RTTR be zero
++ * and then a default diviser for a 32.768KHz clock is used.
++ * Apparently this doesn't work, at least for my SA1110 rev 5.
++ * If the clock divider is uninitialized then reset it to the
++ * default value to get the 1Hz clock.
++ */
++ if (RTTR == 0) {
++ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
++ printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
++ /* The current RTC value probably doesn't make sense either */
++ RCNR = 0;
++ }
++
++ register_rtc(&sa1100_rtc_ops);
++
++ return 0;
++}
++
++static void __exit rtc_exit(void)
++{
++ unregister_rtc(&sa1100_rtc_ops);
++}
++
++module_init(rtc_init);
++module_exit(rtc_exit);
++
++MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>");
++MODULE_DESCRIPTION("SA1100 Realtime Clock Driver (RTC)");
++MODULE_LICENSE("GPL"); /* so says the header */
+Index: linux-2.6.15gum/drivers/char/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/char/Makefile
++++ linux-2.6.15gum/drivers/char/Makefile
+@@ -60,6 +60,7 @@ obj-$(CONFIG_RTC) += rtc.o
+ obj-$(CONFIG_HPET) += hpet.o
+ obj-$(CONFIG_GEN_RTC) += genrtc.o
+ obj-$(CONFIG_EFI_RTC) += efirtc.o
++obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o
+ obj-$(CONFIG_SGI_DS1286) += ds1286.o
+ obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
+ obj-$(CONFIG_DS1302) += ds1302.o
+Index: linux-2.6.15gum/drivers/char/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/char/Kconfig
++++ linux-2.6.15gum/drivers/char/Kconfig
+@@ -790,6 +790,10 @@ config COBALT_LCD
+ This option enables support for the LCD display and buttons found
+ on Cobalt systems through a misc device.
+
++config SA1100_RTC
++ tristate "SA1100/PXA2xx Real Time Clock"
++ depends on ARCH_SA1100 || ARCH_PXA
++
+ config DTLK
+ tristate "Double Talk PC internal speech card support"
+ help
diff --git a/recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch b/recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch
new file mode 100644
index 0000000000..d7d5fda08c
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch
@@ -0,0 +1,34 @@
+diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
+--- a/drivers/mmc/pxamci.c
++++ b/drivers/mmc/pxamci.c
+@@ -71,11 +71,6 @@ struct pxamci_host {
+ unsigned int dma_dir;
+ };
+
+-static inline unsigned int ns_to_clocks(unsigned int ns)
+-{
+- return (ns * (CLOCKRATE / 1000000) + 999) / 1000;
+-}
+-
+ static void pxamci_stop_clock(struct pxamci_host *host)
+ {
+ if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
+@@ -119,6 +114,7 @@ static void pxamci_disable_irq(struct px
+ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
+ {
+ unsigned int nob = data->blocks;
++ unsigned long long clks;
+ unsigned int timeout;
+ u32 dcmd;
+ int i;
+@@ -131,7 +127,9 @@ static void pxamci_setup_data(struct pxa
+ writel(nob, host->base + MMC_NOB);
+ writel(1 << data->blksz_bits, host->base + MMC_BLKLEN);
+
+- timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks;
++ clks = (unsigned long long)data->timeout_ns * CLOCKRATE;
++ do_div(clks, 1000000000UL);
++ timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt);
+ writel((timeout + 255) / 256, host->base + MMC_RDTO);
+
+ if (data->flags & MMC_DATA_READ) {
diff --git a/recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch b/recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch
new file mode 100644
index 0000000000..88442655e4
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch
@@ -0,0 +1,46 @@
+Index: linux-2.6.15gum/drivers/usb/gadget/ether.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/usb/gadget/ether.c
++++ linux-2.6.15gum/drivers/usb/gadget/ether.c
+@@ -2153,6 +2153,29 @@ static u8 __init nibble (unsigned char c
+ return 0;
+ }
+
++/**
++ * gen_serial_ether_addr - Generate software assigned Ethernet address
++ * based on the system_serial number
++ * @addr: Pointer to a six-byte array containing the Ethernet address
++ *
++ * Generate an Ethernet address (MAC) that is not multicast
++ * and has the local assigned bit set, keyed on the system_serial
++ */
++static inline void gen_serial_ether_addr(u8 *addr)
++{
++ static u8 ether_serial_digit = 1;
++ addr [0] = system_serial_high >> 8;
++ addr [1] = system_serial_high;
++ addr [2] = system_serial_low >> 24;
++ addr [3] = system_serial_low >> 16;
++ addr [4] = system_serial_low >> 8;
++ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */
++ (2 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */
++ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */
++ addr [0] &= 0xfe; /* clear multicast bit */
++ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
++}
++
+ static void __init get_ether_addr (const char *str, u8 *dev_addr)
+ {
+ if (str) {
+@@ -2170,7 +2193,10 @@ static void __init get_ether_addr (const
+ if (is_valid_ether_addr (dev_addr))
+ return;
+ }
+- random_ether_addr(dev_addr);
++ if(system_serial_high | system_serial_low)
++ gen_serial_ether_addr(dev_addr);
++ else
++ random_ether_addr(dev_addr);
+ }
+
+ static int __init
diff --git a/recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch b/recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch
new file mode 100644
index 0000000000..920aa53ad8
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch
@@ -0,0 +1,53 @@
+Index: linux-2.6.15gum/drivers/net/smc91x.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/net/smc91x.c
++++ linux-2.6.15gum/drivers/net/smc91x.c
+@@ -1818,6 +1818,30 @@ static int __init smc_findirq(void __iom
+ return probe_irq_off(cookie);
+ }
+
++/**
++ * gen_serial_ether_addr - Generate software assigned Ethernet address
++ * based on the system_serial number
++ * @addr: Pointer to a six-byte array containing the Ethernet address
++ *
++ * Generate an Ethernet address (MAC) that is not multicast
++ * and has the local assigned bit set, keyed on the system_serial
++ */
++static inline void gen_serial_ether_addr(u8 *addr)
++{
++ static u8 ether_serial_digit = 1;
++ addr [0] = system_serial_high >> 8;
++ addr [1] = system_serial_high;
++ addr [2] = system_serial_low >> 24;
++ addr [3] = system_serial_low >> 16;
++ addr [4] = system_serial_low >> 8;
++ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */
++ (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */
++ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */
++ addr [0] &= 0xfe; /* clear multicast bit */
++ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
++}
++
++
+ /*
+ * Function: smc_probe(unsigned long ioaddr)
+ *
+@@ -2036,15 +2060,13 @@ static int __init smc_probe(struct net_d
+ THROTTLE_TX_PKTS ? " [throttle_tx]" : "");
+
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+- printk("%s: Invalid ethernet MAC address. Please "
+- "set using ifconfig\n", dev->name);
+- } else {
++ gen_serial_ether_addr(dev->dev_addr);
++ }
+ /* Print the Ethernet address */
+ printk("%s: Ethernet addr: ", dev->name);
+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x\n", dev->dev_addr[5]);
+- }
+
+ if (lp->phy_type == 0) {
+ PRINTK("%s: No PHY found\n", dev->name);
diff --git a/recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch b/recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch
new file mode 100644
index 0000000000..32a0af5a05
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch
@@ -0,0 +1,84 @@
+Index: linux-2.6.15gum/sound/pci/ac97/ac97_codec.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/pci/ac97/ac97_codec.c
++++ linux-2.6.15gum/sound/pci/ac97/ac97_codec.c
+@@ -150,7 +150,7 @@ static const ac97_codec_id_t snd_ac97_co
+ { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk
+ { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL },
+ { 0x4e534350, 0xffffffff, "LM4550", NULL, NULL },
+-{ 0x50534304, 0xffffffff, "UCB1400", NULL, NULL },
++{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL, AC97_HAS_NO_STD_PCM },
+ { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH },
+ { 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
+ { 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
+Index: linux-2.6.15gum/sound/pci/ac97/ac97_patch.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/pci/ac97/ac97_patch.c
++++ linux-2.6.15gum/sound/pci/ac97/ac97_patch.c
+@@ -375,6 +375,56 @@ int patch_yamaha_ymf753(ac97_t * ac97)
+ }
+
+ /*
++ * UCB1400 codec
++ */
++
++#define AC97_UCB1400_FCSR1 0x6a
++#define AC97_UCB1400_FCSR2 0x6c
++
++static const snd_kcontrol_new_t ucb1400_snd_ac97_controls[] = {
++ AC97_SINGLE("Tone Control - Bass", AC97_UCB1400_FCSR1, 11, 4, 0),
++ AC97_SINGLE("Tone Control - Treble", AC97_UCB1400_FCSR1, 9, 2, 0),
++ AC97_SINGLE("Headphone Playback Switch", AC97_UCB1400_FCSR1, 6, 1, 0),
++ AC97_SINGLE("De-emphasis", AC97_UCB1400_FCSR1, 5, 1, 0),
++ AC97_SINGLE("DC Filter", AC97_UCB1400_FCSR1, 4, 1, 0),
++ AC97_SINGLE("Hi-pass Filter", AC97_UCB1400_FCSR1, 3, 1, 0),
++ AC97_SINGLE("ADC Filter", AC97_UCB1400_FCSR2, 12, 1, 0),
++};
++
++int patch_ucb1400(ac97_t * ac97)
++{
++ int err, i;
++
++ for(i = 0; i < ARRAY_SIZE(ucb1400_snd_ac97_controls); i++) {
++ if((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&ucb1400_snd_ac97_controls[i], ac97))) < 0)
++ return err;
++ }
++
++ snd_ac97_write_cache(ac97, AC97_UCB1400_FCSR1,
++ (0 << 11) | // 0 base boost
++ (0 << 9) | // 0 treble boost
++ (0 << 7) | // Mode = flat
++ (1 << 6) | // Headphones enable
++ (0 << 5) | // De-emphasis disabled
++ (1 << 4) | // DC filter enabled
++ (1 << 3) | // Hi-pass filter enabled
++ (0 << 2) | // disable interrupt signalling via GPIO_INT
++ (1 << 0) // clear ADC overflow status if set
++ );
++
++ snd_ac97_write_cache(ac97, AC97_UCB1400_FCSR2,
++ (0 << 15) | // must be 0
++ (0 << 13) | // must be 0
++ (1 << 12) | // ADC filter enabled
++ (0 << 10) | // must be 0
++ (0 << 4) | // Smart low power mode on neither Codec nor PLL
++ (0 << 0) // must be 0
++ );
++
++ return 0;
++}
++
++/*
+ * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ * removed broken wolfson00 patch.
+ * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
+Index: linux-2.6.15gum/sound/pci/ac97/ac97_patch.h
+===================================================================
+--- linux-2.6.15gum.orig/sound/pci/ac97/ac97_patch.h
++++ linux-2.6.15gum/sound/pci/ac97/ac97_patch.h
+@@ -58,4 +58,5 @@ int patch_cm9780(ac97_t * ac97);
+ int patch_vt1616(ac97_t * ac97);
+ int patch_vt1617a(ac97_t * ac97);
+ int patch_it2646(ac97_t * ac97);
++int patch_ucb1400(ac97_t * ac97);
+ int mpatch_si3036(ac97_t * ac97);
diff --git a/recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch b/recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch
new file mode 100644
index 0000000000..cd7fe41661
--- /dev/null
+++ b/recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch
@@ -0,0 +1,704 @@
+This patch is slightly adjusted from
+
+http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3073/1
+http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3074/2
+http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3075/2
+
+in order to get it to apply cleanly to the released 2.6.15 codebase
+and to put the Kconfig stuff in a more reasonable place in the tree.
+Actually, I think Kconfig should probably separate the notion of the
+touchscreen driver and the AC97-MCP layer thing; but that problem is
+basically in the underlying mcp-based ucb1x00 driver layout in the
+first place.
+Index: linux-2.6.15gum/drivers/mfd/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/Makefile
++++ linux-2.6.15gum/drivers/mfd/Makefile
+@@ -10,3 +10,6 @@ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
++
++obj-$(CONFIG_TOUCHSCREEN_UCB1400) += mcp-ac97.o ucb1x00-core.o ucb1x00-ts.o
++
+Index: linux-2.6.15gum/drivers/mfd/mcp-core.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/mcp-core.c
++++ linux-2.6.15gum/drivers/mfd/mcp-core.c
+@@ -18,7 +18,6 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+
+-#include <asm/dma.h>
+ #include <asm/system.h>
+
+ #include "mcp.h"
+@@ -206,6 +205,7 @@ struct mcp *mcp_host_alloc(struct device
+ mcp->attached_device.bus = &mcp_bus_type;
+ mcp->attached_device.dma_mask = parent->dma_mask;
+ mcp->attached_device.release = mcp_release;
++ mcp->dev = &mcp->attached_device;
+ }
+ return mcp;
+ }
+Index: linux-2.6.15gum/drivers/mfd/mcp-sa11x0.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/mcp-sa11x0.c
++++ linux-2.6.15gum/drivers/mfd/mcp-sa11x0.c
+@@ -31,8 +31,12 @@
+ #include "mcp.h"
+
+ struct mcp_sa11x0 {
+- u32 mccr0;
+- u32 mccr1;
++ u32 mccr0;
++ u32 mccr1;
++ dma_device_t dma_audio_rd;
++ dma_device_t dma_audio_wr;
++ dma_device_t dma_telco_rd;
++ dma_device_t dma_telco_wr;
+ };
+
+ #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
+@@ -159,10 +163,10 @@ static int mcp_sa11x0_probe(struct platf
+ mcp->owner = THIS_MODULE;
+ mcp->ops = &mcp_sa11x0;
+ mcp->sclk_rate = data->sclk_rate;
+- mcp->dma_audio_rd = DMA_Ser4MCP0Rd;
+- mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
+- mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
+- mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
++ priv(mcp)->dma_audio_rd = DMA_Ser4MCP0Rd;
++ priv(mcp)->dma_audio_wr = DMA_Ser4MCP0Wr;
++ priv(mcp)->dma_telco_rd = DMA_Ser4MCP1Rd;
++ priv(mcp)->dma_telco_wr = DMA_Ser4MCP1Wr;
+
+ platform_set_drvdata(pdev, mcp);
+
+Index: linux-2.6.15gum/drivers/mfd/mcp.h
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/mcp.h
++++ linux-2.6.15gum/drivers/mfd/mcp.h
+@@ -19,11 +19,8 @@ struct mcp {
+ int use_count;
+ unsigned int sclk_rate;
+ unsigned int rw_timeout;
+- dma_device_t dma_audio_rd;
+- dma_device_t dma_audio_wr;
+- dma_device_t dma_telco_rd;
+- dma_device_t dma_telco_wr;
+ struct device attached_device;
++ struct device *dev;
+ };
+
+ struct mcp_ops {
+Index: linux-2.6.15gum/drivers/mfd/ucb1x00-assabet.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/ucb1x00-assabet.c
++++ linux-2.6.15gum/drivers/mfd/ucb1x00-assabet.c
+@@ -15,8 +15,6 @@
+ #include <linux/proc_fs.h>
+ #include <linux/device.h>
+
+-#include <asm/dma.h>
+-
+ #include "ucb1x00.h"
+
+ #define UCB1X00_ATTR(name,input)\
+Index: linux-2.6.15gum/drivers/mfd/ucb1x00-core.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/ucb1x00-core.c
++++ linux-2.6.15gum/drivers/mfd/ucb1x00-core.c
+@@ -23,14 +23,17 @@
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/interrupt.h>
++#include <linux/kthread.h>
+ #include <linux/device.h>
+
+-#include <asm/dma.h>
+-#include <asm/hardware.h>
+-#include <asm/irq.h>
+-
+ #include "ucb1x00.h"
+
++#ifdef CONFIG_UCB1400
++#define UCB_IS_1400(id) ((id) == UCB_ID_1400)
++#else
++#define UCB_IS_1400(id) (0)
++#endif
++
+ static DECLARE_MUTEX(ucb1x00_sem);
+ static LIST_HEAD(ucb1x00_drivers);
+ static LIST_HEAD(ucb1x00_devices);
+@@ -58,9 +61,9 @@ void ucb1x00_io_set_dir(struct ucb1x00 *
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ ucb->io_dir |= out;
+ ucb->io_dir &= ~in;
++ spin_unlock_irqrestore(&ucb->io_lock, flags);
+
+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+- spin_unlock_irqrestore(&ucb->io_lock, flags);
+ }
+
+ /**
+@@ -86,9 +89,9 @@ void ucb1x00_io_write(struct ucb1x00 *uc
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ ucb->io_out |= set;
+ ucb->io_out &= ~clear;
++ spin_unlock_irqrestore(&ucb->io_lock, flags);
+
+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+- spin_unlock_irqrestore(&ucb->io_lock, flags);
+ }
+
+ /**
+@@ -178,7 +181,7 @@ unsigned int ucb1x00_adc_read(struct ucb
+ schedule_timeout(1);
+ }
+
+- return UCB_ADC_DAT(val);
++ return UCB_IS_1400(ucb->id) ? (val & 0x3ff) : ((val & 0x7fe0) >> 5);
+ }
+
+ /**
+@@ -223,6 +226,47 @@ static irqreturn_t ucb1x00_irq(int irqnr
+ return IRQ_HANDLED;
+ }
+
++/*
++ * A restriction with interrupts exists when using the ucb1400, as
++ * the codec read/write routines may sleep while waiting for codec
++ * access completion and uses semaphores for access control to the
++ * AC97 bus. A complete codec read cycle could take anywhere from
++ * 60 to 100uSec so we *definitely* don't want to spin inside the
++ * interrupt handler waiting for codec access. So, we handle the
++ * interrupt by scheduling a RT kernel thread to run in process
++ * context instead of interrupt context.
++ */
++static int ucb1x00_thread(void *_ucb)
++{
++ struct task_struct *tsk = current;
++ struct ucb1x00 *ucb = _ucb;
++
++ tsk->policy = SCHED_FIFO;
++ tsk->rt_priority = 1;
++
++ while (!kthread_should_stop()) {
++ wait_for_completion_interruptible(&ucb->irq_wait);
++ if (try_to_freeze())
++ continue;
++ ucb1x00_irq(ucb->irq, ucb, NULL);
++ enable_irq(ucb->irq);
++ }
++
++ ucb->irq_task = NULL;
++ return 0;
++}
++
++static irqreturn_t ucb1x00_threaded_irq(int irqnr, void *devid, struct pt_regs *regs)
++{
++ struct ucb1x00 *ucb = devid;
++ if (irqnr == ucb->irq) {
++ disable_irq(ucb->irq);
++ complete(&ucb->irq_wait);
++ return IRQ_HANDLED;
++ }
++ return IRQ_NONE;
++}
++
+ /**
+ * ucb1x00_hook_irq - hook a UCB1x00 interrupt
+ * @ucb: UCB1x00 structure describing chip
+@@ -276,18 +320,22 @@ void ucb1x00_enable_irq(struct ucb1x00 *
+
+ if (idx < 16) {
+ spin_lock_irqsave(&ucb->lock, flags);
+-
+- ucb1x00_enable(ucb);
+- if (edges & UCB_RISING) {
++ if (edges & UCB_RISING)
+ ucb->irq_ris_enbl |= 1 << idx;
+- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+- }
+- if (edges & UCB_FALLING) {
++ if (edges & UCB_FALLING)
+ ucb->irq_fal_enbl |= 1 << idx;
+- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+- }
+- ucb1x00_disable(ucb);
+ spin_unlock_irqrestore(&ucb->lock, flags);
++
++ ucb1x00_enable(ucb);
++
++ /* This prevents spurious interrupts on the UCB1400 */
++ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx);
++ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
++
++ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
++ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
++
++ ucb1x00_disable(ucb);
+ }
+ }
+
+@@ -305,18 +353,16 @@ void ucb1x00_disable_irq(struct ucb1x00
+
+ if (idx < 16) {
+ spin_lock_irqsave(&ucb->lock, flags);
+-
+- ucb1x00_enable(ucb);
+- if (edges & UCB_RISING) {
++ if (edges & UCB_RISING)
+ ucb->irq_ris_enbl &= ~(1 << idx);
+- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+- }
+- if (edges & UCB_FALLING) {
++ if (edges & UCB_FALLING)
+ ucb->irq_fal_enbl &= ~(1 << idx);
+- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+- }
+- ucb1x00_disable(ucb);
+ spin_unlock_irqrestore(&ucb->lock, flags);
++
++ ucb1x00_enable(ucb);
++ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
++ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
++ ucb1x00_disable(ucb);
+ }
+ }
+
+@@ -349,16 +395,17 @@ int ucb1x00_free_irq(struct ucb1x00 *ucb
+ ucb->irq_ris_enbl &= ~(1 << idx);
+ ucb->irq_fal_enbl &= ~(1 << idx);
+
+- ucb1x00_enable(ucb);
+- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
+- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
+- ucb1x00_disable(ucb);
+-
+ irq->fn = NULL;
+ irq->devid = NULL;
+ ret = 0;
+ }
+ spin_unlock_irq(&ucb->lock);
++
++ ucb1x00_enable(ucb);
++ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
++ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
++ ucb1x00_disable(ucb);
++
+ return ret;
+
+ bad:
+@@ -478,7 +525,7 @@ static int ucb1x00_probe(struct mcp *mcp
+ mcp_enable(mcp);
+ id = mcp_reg_read(mcp, UCB_ID);
+
+- if (id != UCB_ID_1200 && id != UCB_ID_1300) {
++ if (id != UCB_ID_1200 && id != UCB_ID_1300 && !UCB_IS_1400(id)) {
+ printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
+ goto err_disable;
+ }
+@@ -491,12 +538,13 @@ static int ucb1x00_probe(struct mcp *mcp
+ memset(ucb, 0, sizeof(struct ucb1x00));
+
+ ucb->cdev.class = &ucb1x00_class;
+- ucb->cdev.dev = &mcp->attached_device;
++ ucb->cdev.dev = mcp->dev;
+ strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id));
+
+ spin_lock_init(&ucb->lock);
+ spin_lock_init(&ucb->io_lock);
+ sema_init(&ucb->adc_sem, 1);
++ init_completion(&ucb->irq_wait);
+
+ ucb->id = id;
+ ucb->mcp = mcp;
+@@ -507,12 +555,22 @@ static int ucb1x00_probe(struct mcp *mcp
+ goto err_free;
+ }
+
+- ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb);
++ ret = request_irq(ucb->irq,
++ UCB_IS_1400(id) ? ucb1x00_threaded_irq : ucb1x00_irq,
++ 0, "UCB1x00", ucb);
+ if (ret) {
+ printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
+ ucb->irq, ret);
+ goto err_free;
+ }
++ if (UCB_IS_1400(id)) {
++ ucb->irq_task = kthread_run(ucb1x00_thread, ucb, "kUCB1x00d");
++ if (IS_ERR(ucb->irq_task)) {
++ ret = PTR_ERR(ucb->irq_task);
++ ucb->irq_task = NULL;
++ goto err_irq;
++ }
++ }
+
+ set_irq_type(ucb->irq, IRQT_RISING);
+ mcp_set_drvdata(mcp, ucb);
+@@ -531,6 +589,8 @@ static int ucb1x00_probe(struct mcp *mcp
+ goto out;
+
+ err_irq:
++ if (UCB_IS_1400(id) && ucb->irq_task)
++ kthread_stop(ucb->irq_task);
+ free_irq(ucb->irq, ucb);
+ err_free:
+ kfree(ucb);
+@@ -553,6 +613,8 @@ static void ucb1x00_remove(struct mcp *m
+ }
+ up(&ucb1x00_sem);
+
++ if (UCB_IS_1400(ucb->id) && ucb->irq_task)
++ kthread_stop(ucb->irq_task);
+ free_irq(ucb->irq, ucb);
+ class_device_unregister(&ucb->cdev);
+ }
+Index: linux-2.6.15gum/drivers/mfd/ucb1x00-ts.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/ucb1x00-ts.c
++++ linux-2.6.15gum/drivers/mfd/ucb1x00-ts.c
+@@ -34,10 +34,8 @@
+ #include <linux/kthread.h>
+ #include <linux/delay.h>
+
+-#include <asm/dma.h>
+-#include <asm/semaphore.h>
+-#include <asm/arch/collie.h>
+ #include <asm/mach-types.h>
++#include <asm/arch-sa1100/collie.h>
+
+ #include "ucb1x00.h"
+
+@@ -46,7 +44,7 @@ struct ucb1x00_ts {
+ struct input_dev *idev;
+ struct ucb1x00 *ucb;
+
+- wait_queue_head_t irq_wait;
++ struct completion irq_wait;
+ struct task_struct *rtask;
+ u16 x_res;
+ u16 y_res;
+@@ -206,7 +204,6 @@ static int ucb1x00_thread(void *_ts)
+ {
+ struct ucb1x00_ts *ts = _ts;
+ struct task_struct *tsk = current;
+- DECLARE_WAITQUEUE(wait, tsk);
+ int valid;
+
+ /*
+@@ -218,10 +215,8 @@ static int ucb1x00_thread(void *_ts)
+
+ valid = 0;
+
+- add_wait_queue(&ts->irq_wait, &wait);
+ while (!kthread_should_stop()) {
+ unsigned int x, y, p;
+- signed long timeout;
+
+ ts->restart = 0;
+
+@@ -243,8 +238,6 @@ static int ucb1x00_thread(void *_ts)
+
+
+ if (ucb1x00_ts_pen_down(ts)) {
+- set_task_state(tsk, TASK_INTERRUPTIBLE);
+-
+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
+ ucb1x00_disable(ts->ucb);
+
+@@ -257,7 +250,15 @@ static int ucb1x00_thread(void *_ts)
+ valid = 0;
+ }
+
+- timeout = MAX_SCHEDULE_TIMEOUT;
++ /*
++ * Since ucb1x00_enable_irq() might sleep due
++ * to the way the UCB1400 regs are accessed, we
++ * can't use set_task_state() before that call,
++ * and not changing state before enabling the
++ * interrupt is racy. A completion handler avoids
++ * the issue.
++ */
++ wait_for_completion_interruptible(&ts->irq_wait);
+ } else {
+ ucb1x00_disable(ts->ucb);
+
+@@ -272,16 +273,12 @@ static int ucb1x00_thread(void *_ts)
+ }
+
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+- timeout = HZ / 100;
++ schedule_timeout(HZ/100);
+ }
+
+ try_to_freeze();
+-
+- schedule_timeout(timeout);
+ }
+
+- remove_wait_queue(&ts->irq_wait, &wait);
+-
+ ts->rtask = NULL;
+ return 0;
+ }
+@@ -294,7 +291,7 @@ static void ucb1x00_ts_irq(int idx, void
+ {
+ struct ucb1x00_ts *ts = id;
+ ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+- wake_up(&ts->irq_wait);
++ complete(&ts->irq_wait);
+ }
+
+ static int ucb1x00_ts_open(struct input_dev *idev)
+@@ -304,7 +301,7 @@ static int ucb1x00_ts_open(struct input_
+
+ BUG_ON(ts->rtask);
+
+- init_waitqueue_head(&ts->irq_wait);
++ init_completion(&ts->irq_wait);
+ ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
+ if (ret < 0)
+ goto out;
+@@ -359,7 +356,7 @@ static int ucb1x00_ts_resume(struct ucb1
+ * after sleep.
+ */
+ ts->restart = 1;
+- wake_up(&ts->irq_wait);
++ complete(&ts->irq_wait);
+ }
+ return 0;
+ }
+Index: linux-2.6.15gum/drivers/mfd/ucb1x00.h
+===================================================================
+--- linux-2.6.15gum.orig/drivers/mfd/ucb1x00.h
++++ linux-2.6.15gum/drivers/mfd/ucb1x00.h
+@@ -94,6 +94,7 @@
+ #define UCB_ID 0x0c
+ #define UCB_ID_1200 0x1004
+ #define UCB_ID_1300 0x1005
++#define UCB_ID_1400 0x4304
+
+ #define UCB_MODE 0x0d
+ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
+@@ -110,6 +111,8 @@ struct ucb1x00 {
+ spinlock_t lock;
+ struct mcp *mcp;
+ unsigned int irq;
++ struct task_struct *irq_task;
++ struct completion irq_wait;
+ struct semaphore adc_sem;
+ spinlock_t io_lock;
+ u16 id;
+@@ -122,6 +125,7 @@ struct ucb1x00 {
+ struct class_device cdev;
+ struct list_head node;
+ struct list_head devs;
++
+ };
+
+ struct ucb1x00_driver;
+Index: linux-2.6.15gum/drivers/mfd/mcp-ac97.c
+===================================================================
+--- /dev/null
++++ linux-2.6.15gum/drivers/mfd/mcp-ac97.c
+@@ -0,0 +1,153 @@
++/*
++ * linux/drivers/misc/mcp-ac97.c
++ *
++ * Author: Nicolas Pitre
++ * Created: Jan 14, 2005
++ * Copyright: (C) MontaVista Software Inc.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This module provides the minimum replacement for mcp-core.c allowing for
++ * the UCB1400 chip to be driven by the ucb1x00 driver over an AC97 link.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/device.h>
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/ac97_codec.h>
++
++#include "mcp.h"
++
++/* ucb1x00 SIB register to ucb1400 AC-link register mapping */
++
++static const unsigned char regmap[] = {
++ 0x5a, /* UCB_IO_DATA */
++ 0X5C, /* UCB_IO_DIR */
++ 0X5E, /* UCB_IE_RIS */
++ 0x60, /* UCB_IE_FAL */
++ 0x62, /* UCB_IE_STATUS */
++ 0, /* UCB_TC_A */
++ 0, /* UCB_TC_B */
++ 0, /* UCB_AC_A */
++ 0, /* UCB_AC_B */
++ 0x64, /* UCB_TS_CR */
++ 0x66, /* UCB_ADC_CR */
++ 0x68, /* UCB_ADC_DATA */
++ 0x7e, /* UCB_ID */
++ 0, /* UCB_MODE */
++};
++
++unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
++{
++ ac97_t *ac97 = to_ac97_t(mcp->dev);
++ if (reg < ARRAY_SIZE(regmap)) {
++ reg = regmap[reg];
++ if (reg)
++ return ac97->bus->ops->read(ac97, reg);
++ }
++ return -1;
++}
++EXPORT_SYMBOL(mcp_reg_read);
++
++void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
++{
++ ac97_t *ac97 = to_ac97_t(mcp->dev);
++ if (reg < ARRAY_SIZE(regmap)) {
++ reg = regmap[reg];
++ if (reg)
++ ac97->bus->ops->write(ac97, reg, val);
++ }
++}
++EXPORT_SYMBOL(mcp_reg_write);
++
++void mcp_enable(struct mcp *mcp)
++{
++}
++EXPORT_SYMBOL(mcp_enable);
++
++void mcp_disable(struct mcp *mcp)
++{
++}
++EXPORT_SYMBOL(mcp_disable);
++
++#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
++
++static int mcp_probe(struct device *dev)
++{
++ struct mcp_driver *drv = to_mcp_driver(dev->driver);
++ struct mcp *mcp;
++ int ret;
++
++ ret = -ENOMEM;
++ mcp = kmalloc(sizeof(*mcp), GFP_KERNEL);
++ if (mcp) {
++ memset(mcp, 0, sizeof(*mcp));
++ mcp->owner = THIS_MODULE;
++ mcp->dev = dev;
++ ret = drv->probe(mcp);
++ if (ret)
++ kfree(mcp);
++ }
++ if (!ret)
++ dev_set_drvdata(dev, mcp);
++ return ret;
++}
++
++static int mcp_remove(struct device *dev)
++{
++ struct mcp_driver *drv = to_mcp_driver(dev->driver);
++ struct mcp *mcp = dev_get_drvdata(dev);
++
++ drv->remove(mcp);
++ dev_set_drvdata(dev, NULL);
++ kfree(mcp);
++ return 0;
++}
++
++static int mcp_suspend(struct device *dev, pm_message_t state)
++{
++ struct mcp_driver *drv = to_mcp_driver(dev->driver);
++ struct mcp *mcp = dev_get_drvdata(dev);
++ int ret = 0;
++
++ if (drv->suspend)
++ ret = drv->suspend(mcp, state);
++ return ret;
++}
++
++static int mcp_resume(struct device *dev)
++{
++ struct mcp_driver *drv = to_mcp_driver(dev->driver);
++ struct mcp *mcp = dev_get_drvdata(dev);
++ int ret = 0;
++
++ if (drv->resume)
++ ret = drv->resume(mcp);
++ return ret;
++}
++
++int mcp_driver_register(struct mcp_driver *mcpdrv)
++{
++ mcpdrv->drv.owner = THIS_MODULE;
++ mcpdrv->drv.bus = &ac97_bus_type;
++ mcpdrv->drv.probe = mcp_probe;
++ mcpdrv->drv.remove = mcp_remove;
++ mcpdrv->drv.suspend = mcp_suspend;
++ mcpdrv->drv.resume = mcp_resume;
++ return driver_register(&mcpdrv->drv);
++}
++EXPORT_SYMBOL(mcp_driver_register);
++
++void mcp_driver_unregister(struct mcp_driver *mcpdrv)
++{
++ driver_unregister(&mcpdrv->drv);
++}
++EXPORT_SYMBOL(mcp_driver_unregister);
++
++MODULE_LICENSE("GPL");
+Index: linux-2.6.15gum/drivers/input/touchscreen/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/input/touchscreen/Kconfig
++++ linux-2.6.15gum/drivers/input/touchscreen/Kconfig
+@@ -11,6 +11,25 @@ menuconfig INPUT_TOUCHSCREEN
+
+ if INPUT_TOUCHSCREEN
+
++config UCB1400
++ bool
++
++config TOUCHSCREEN_UCB1400
++ tristate "UCB1400 Touchscreen support"
++ depends on ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_GUMSTIX
++ select SND_AC97_BUS
++ select UCB1400
++ help
++ Say Y here if you have a touchscreen connected to a UCB1400 ADC chip
++ on the AC97 bus of a PXA255/PXA270 host.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called ucb1x00-ts. It will also build the modules
++ ucb1x00-core and mcp-ac97 which provide the compatibility layers
++ down to the AC97 bus.
++
+ config TOUCHSCREEN_BITSY
+ tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
+ depends on SA1100_BITSY
+Index: linux-2.6.15gum/drivers/input/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/drivers/input/Kconfig
++++ linux-2.6.15gum/drivers/input/Kconfig
+@@ -87,7 +87,7 @@ config INPUT_JOYDEV
+ module will be called joydev.
+
+ config INPUT_TSDEV
+- tristate "Touchscreen interface"
++ tristate "Compaq touchscreen interface"
+ ---help---
+ Say Y here if you have an application that only can understand the
+ Compaq touchscreen protocol for absolute pointer data. This is