diff options
Diffstat (limited to 'recipes/linux/linux-gumstix-2.6.15')
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 |