Index: include/asm-arm/arch-imx/hardware.h =================================================================== --- a/include/asm-arm/arch-imx/hardware.h (.../vanilla/linux-2.6.10) (revision 490) +++ b/include/asm-arm/arch-imx/hardware.h (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -98,4 +98,12 @@ #include "mx1ads.h" #endif +#ifdef CONFIG_MACH_MX1FS2 +#include "mx1fs2.h" #endif + +#ifdef CONFIG_MACH_SCB9328 +#include "scb9328.h" +#endif + +#endif Index: include/asm-arm/arch-imx/mx1ads.h =================================================================== --- a/include/asm-arm/arch-imx/mx1ads.h (.../vanilla/linux-2.6.10) (revision 490) +++ b/include/asm-arm/arch-imx/mx1ads.h (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -26,7 +26,11 @@ /* Memory Map for the M9328MX1ADS (MX1ADS) Board */ /* ------------------------------------------------------------------------ */ -#define MX1ADS_FLASH_PHYS 0x10000000 +/* + * FIXME: 2.6.9-imx suggested this to be 0x10000000? Was inconsistent + * between this file and drivers/mtd/maps/mx1ads.c [RSC] + */ +#define MX1ADS_FLASH_PHYS 0x0C000000 #define MX1ADS_FLASH_SIZE (16*1024*1024) #define IMX_FB_PHYS (0x0C000000 - 0x40000) Index: include/asm-arm/arch-imx/scb9328.h =================================================================== --- a/include/asm-arm/arch-imx/scb9328.h (revision 0) +++ b/include/asm-arm/arch-imx/scb9328.h (revision 490) @@ -0,0 +1,61 @@ +/* + * linux/include/asm-arm/arch-imx/scb9328.h + * + * Copyright (C) 2005 Robert Schwebel, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_SCB9328_H +#define __ASM_ARCH_SCB9328_H + +/* ------------------------------------------------------------------------ */ +/* Memory Map for the SCB9328 Board */ +/* ------------------------------------------------------------------------ */ + +/* we have two 16c550 on our eval board */ +#define SCB9328_UART1_VIRT ( IMX_CS3_VIRT + 0x30000 ) +#define SCB9328_UART1_PHYS ( IMX_CS3_PHYS + 0x30000 ) +#define SCB9328_UART1_IRQ IRQ_GPIOA(1) + +#define SCB9328_UART2_VIRT ( IMX_CS3_VIRT + 0x10000 ) +#define SCB9328_UART2_PHYS ( IMX_CS3_PHYS + 0x10000 ) +#define SCB9328_UART2_IRQ IRQ_GPIOA(1) + +/* ethernet chip */ +#define SCB9328_ETH_VIRT ( IMX_CS5_VIRT ) +#define SCB9328_ETH_PHYS ( IMX_CS5_PHYS ) +#define SCB9328_ETH_IRQ ( IRQ_GPIOC(3) ) + +/* flash */ +#define SCB9328_FLASH_PHYS IMX_CS0_PHYS +#ifdef CONFIG_IMX_SCB9328_FLASH_16MB +# define SCB9328_FLASH_SIZE 0x01000000 +#endif +#ifdef CONFIG_IMX_SCB9328_FLASH_32MB +# define SCB9328_FLASH_SIZE 0x02000000 +#endif +#define SCB9328_FLASH_BASE IMX_CS0_VIRT + +#define CLK32 32768 + +#ifndef __ASSEMBLER__ +void scb9328_ledon(int); +void scb9328_ledoff(int); +int scb9328_get_buttons(void); +#endif + +#endif /* __ASM_ARCH_SCB9328_H */ Index: include/asm-arm/arch-imx/imxfb.h =================================================================== --- a/include/asm-arm/arch-imx/imxfb.h (revision 0) +++ b/include/asm-arm/arch-imx/imxfb.h (revision 490) @@ -0,0 +1,32 @@ +/* + * This structure describes the machine which we are running on. + */ +struct imxfb_mach_info { + u_long pixclock; + + u_short xres; + u_short yres; + + u_char bpp; + u_char hsync_len; + u_char left_margin; + u_char right_margin; + + u_char vsync_len; + u_char upper_margin; + u_char lower_margin; + u_char sync; + + u_int cmap_greyscale:1, + cmap_inverse:1, + cmap_static:1, + unused:29; + + u_int pcr; + u_int pwmr; + u_int lscr1; + + void (*lcd_power)(int); + void (*backlight_power)(int); +}; +void set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info); Index: include/asm-arm/arch-imx/mmc.h =================================================================== --- a/include/asm-arm/arch-imx/mmc.h (revision 0) +++ b/include/asm-arm/arch-imx/mmc.h (revision 490) @@ -0,0 +1,12 @@ +#ifndef ASMARM_ARCH_MMC_H +#define ASMARM_ARCH_MMC_H + +#include + +struct imxmmc_platform_data { + int (*card_present)(void); +}; + +extern void imx_set_mmc_info(struct imxmmc_platform_data *info); + +#endif Index: include/asm-arm/arch-imx/mx1fs2.h =================================================================== --- a/include/asm-arm/arch-imx/mx1fs2.h (revision 0) +++ b/include/asm-arm/arch-imx/mx1fs2.h (revision 490) @@ -0,0 +1,51 @@ +/* + * linux/include/asm-arm/arch-imx/mx1fs2.h + * + * Copyright (C) 2004 Robert Schwebel, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_MX1FS2_H +#define __ASM_ARCH_MX1FS2_H + +/* ------------------------------------------------------------------------ */ +/* Memory Map for the FS2 Board */ +/* ------------------------------------------------------------------------ */ + +#define MX1FS2_FLASH_PHYS 0x10000000 +#define MX1FS2_FLASH_SIZE (16*1024*1024) + +#define IMX_FB_PHYS (0x0C000000 - 0x40000) + +/* external uart 1 */ +#define MX1FS2_UART1_VIRT ( IMX_CS4_VIRT ) +#define MX1FS2_UART1_PHYS ( IMX_CS4_PHYS ) +#define MX1FS2_UART1_IRQ IRQ_GPIOC(10) + +/* external uart 2 */ +#define MX1FS2_UART2_VIRT ( IMX_CS5_VIRT ) +#define MX1FS2_UART2_PHYS ( IMX_CS5_PHYS ) +#define MX1FS2_UART2_IRQ IRQ_GPIOC(9) + +/* external LPT port */ +#define MX1FS2_LPT_VIRT ( IMX_CS1_VIRT ) +#define MX1FS2_LPT_PHYS ( IMX_CS1_PHYS ) + + +#define CLK32 32768 + +#endif /* __ASM_ARCH_MX1FS2_H */ Index: include/asm-arm/arch-imx/system.h =================================================================== --- a/include/asm-arm/arch-imx/system.h (.../vanilla/linux-2.6.10) (revision 490) +++ b/include/asm-arm/arch-imx/system.h (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -21,6 +21,8 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H +#include + static void arch_idle(void) { @@ -34,6 +36,9 @@ static inline void arch_reset(char mode) { + /* disable LCD controller */ +// LCDC_RMCR &= ~RMCR_LCDC_EN; + cpu_reset(0); } Index: README.PTX =================================================================== --- a/README.PTX (revision 0) +++ b/README.PTX (revision 490) @@ -0,0 +1,15 @@ +README.PTX +---------- + +Potential problems between 2.6.9-imx1 and 2.6.10-trunk: + +- check start of MTD map; was decleared inconsistently in two + places (mapping driver and board specific header file) + +- check additional serial port configuration for mx1fs2 and + scb9326 (arch/arm/mach-imx/[mx1fs2|scb9326].c) for correctness + +- drivers/net/dm9000.c wants to include linux/dm9000.h which does + not exist (and didn't exist in 2.6.9-imx1). + +RSC, 2005-01-04 Index: arch/arm/mach-imx/time.c =================================================================== --- a/arch/arm/mach-imx/time.c (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/time.c (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -1,13 +1,14 @@ /* - * linux/arch/arm/mach-imx/time.c + * linux/arch/arm/mach-imx/time.c * - * Copyright (C) 2000-2001 Deep Blue Solutions - * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright (C) 2004 Pengutronix + * Author: Sascha Hauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + #include #include #include Index: arch/arm/mach-imx/Makefile.boot =================================================================== --- a/arch/arm/mach-imx/Makefile.boot (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/Makefile.boot (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -1,2 +1,3 @@ zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000 - + zreladdr-$(CONFIG_MACH_SCB9328) := 0x08008000 + zreladdr-$(CONFIG_MACH_MX1FS2) := 0x08008000 Index: arch/arm/mach-imx/Kconfig =================================================================== --- a/arch/arm/mach-imx/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -1,10 +1,54 @@ menu "IMX Implementations" depends on ARCH_IMX +config MACH_MX1FS2 + bool "mx1fs2" + depends on ARCH_IMX + help + Say Y here if you are using the viasys mx1fs2 board + +config MACH_SCB9328 + bool "scb9328" + depends on ARCH_IMX + help + Say Y here if you are using the Synertronixx scb9328 board + config ARCH_MX1ADS bool "mx1ads" depends on ARCH_IMX help Say Y here if you are using the Motorola MX1ADS board +choice + prompt "SCB9328 eval board" + depends on MACH_SCB9328 + default IMX_SCB9328_EVK9328 + +config IMX_SCB9328_EVK9328 + bool "use evk9328 eval board" + depends on MACH_SCB9328 + help + Say Y here if you are using the Synertronixx EVK9328 eval board + +config IMX_SCB9328_EVK9328L + bool "use evk9328l eval board" + depends on MACH_SCB9328 + help + Say Y here if you are using the Synertronixx EVK9328 light eval board + +endchoice + +choice + prompt "SCB9328 Flash available" + depends on MACH_SCB9328 + default IMX_SCB9328_FLASH_16MB + +config IMX_SCB9328_FLASH_16MB + bool "16MB" + +config IMX_SCB9328_FLASH_32MB + bool "32MB" + +endchoice + endmenu Index: arch/arm/mach-imx/dma.c =================================================================== --- a/arch/arm/mach-imx/dma.c (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/dma.c (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -136,7 +136,7 @@ i, channel->name); DBOSR |= (1 << i); } - DISR |= (1 << i); + DISR = (1 << i); } return IRQ_HANDLED; } @@ -158,10 +158,10 @@ */ printk(KERN_WARNING "spurious IRQ for DMA channel %d\n", i); - DISR |= (1 << i); } } } + DISR = disr; return IRQ_HANDLED; } Index: arch/arm/mach-imx/cpufreq.c =================================================================== --- a/arch/arm/mach-imx/cpufreq.c (revision 0) +++ b/arch/arm/mach-imx/cpufreq.c (revision 490) @@ -0,0 +1,107 @@ +/* + * linux/arch/arm/mach-imx/cpufreq.c + * + * Copyright (c) 2004 Sascha Hauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include + +#include + +static int cur_freq = 200000; + +static struct cpufreq_frequency_table imx_cpu_freqs[] = { + {0x040e200e, 150000}, + {0x00321431, 200000}, + {0, CPUFREQ_TABLE_END}, +}; + +unsigned int imx_getspeed(void) +{ + return cur_freq; +} + +static int imx_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int cur = imx_getspeed(); + unsigned int index; + + struct cpufreq_freqs freqs; + + cpufreq_frequency_table_target(policy, imx_cpu_freqs, + target_freq, relation, &index); + switch(relation){ + case CPUFREQ_RELATION_L: + break; + case CPUFREQ_RELATION_H: + break; + } + + freqs.old = cur; + freqs.new = imx_cpu_freqs[index].frequency; + freqs.cpu = 0; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + cur_freq = imx_cpu_freqs[index].frequency; + MPCTL0 = imx_cpu_freqs[index].index; + CSCR |= CSCR_MPLL_RESTART; + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +static int __init imx_cpu_init(struct cpufreq_policy *policy) +{ + if (policy->cpu != 0) + return -EINVAL; + + cpufreq_frequency_table_cpuinfo(policy,imx_cpu_freqs); + + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + cur_freq = 200000; + return 0; +} + +int imx_verify_speed(struct cpufreq_policy *policy) +{ + if (policy->cpu) + return -EINVAL; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); + + /* make sure that at least one frequency is within the policy */ + cpufreq_frequency_table_verify(policy,imx_cpu_freqs); + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); + + return 0; +} + +static struct cpufreq_driver imx_driver = { + .verify = imx_verify_speed, + .target = imx_target, + .init = imx_cpu_init, + .name = "imx", +}; + +static int __init cpufreq_init(void) +{ + cpufreq_gov_userspace_init(); + /* FIXME implement checking for correct cpu */ + return cpufreq_register_driver(&imx_driver); +} + +arch_initcall(cpufreq_init); Index: arch/arm/mach-imx/generic.c =================================================================== --- a/arch/arm/mach-imx/generic.c (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/generic.c (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -29,6 +29,8 @@ #include #include +#include +#include void imx_gpio_mode(int gpio_mode) { @@ -171,13 +173,25 @@ }, }; +static u64 imxmmmc_dmamask = 0xffffffffUL; + static struct platform_device imx_mmc_device = { .name = "imx-mmc", .id = 0, + .dev = { + .dma_mask = &imxmmmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, .num_resources = ARRAY_SIZE(imx_mmc_resources), .resource = imx_mmc_resources, }; +void __init imx_set_mmc_info(struct imxmmc_platform_data *info) +{ + imx_mmc_device.dev.platform_data = info; +} +EXPORT_SYMBOL(imx_set_mmc_info); + static struct resource imx_uart1_resources[] = { [0] = { .start = 0x00206000, @@ -228,6 +242,14 @@ .resource = imx_uart2_resources, }; +static struct imxfb_mach_info imx_fb_info; + +void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info) +{ + memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info)); +} +EXPORT_SYMBOL(set_imx_fb_info); + static struct resource imxfb_resources[] = { [0] = { .start = 0x00205000, @@ -241,9 +263,16 @@ }, }; +static u64 fb_dma_mask = ~(u64)0; + static struct platform_device imxfb_device = { .name = "imx-fb", .id = 0, + .dev = { + .platform_data = &imx_fb_info, + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, .num_resources = ARRAY_SIZE(imxfb_resources), .resource = imxfb_resources, }; Index: arch/arm/mach-imx/mx1fs2.c =================================================================== --- a/arch/arm/mach-imx/mx1fs2.c (revision 0) +++ b/arch/arm/mach-imx/mx1fs2.c (revision 490) @@ -0,0 +1,165 @@ +/* + * linux/arch/arm/mach-imx/mx1fs2.c + * + * Copyright (c) 2004 Sascha Hauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + +static struct map_desc mx1fs2_io_desc[] __initdata = { + /* virtual physical length type */ + {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE}, + {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE}, + {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE}, + {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE}, + {IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE}, + {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE}, + {IMX_FB_VIRT, IMX_FB_PHYS, IMX_FB_SIZE, MT_DEVICE}, +}; + +#warning Some of these serial port entries have only been guessed... + +static struct uart_port mx1fs2_serial_ports[2] = { + { + .membase = (char *)(MX1FS2_UART1_VIRT), + .mapbase = (unsigned long)(MX1FS2_UART1_PHYS), + .irq = MX1FS2_UART1_IRQ, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = 3686400 / 16, + .line = 1, + .type = PORT_16550, + .fifosize = 16 + }, { + .membase = (char *)(MX1FS2_UART2_VIRT), + .mapbase = (unsigned long)(MX1FS2_UART2_PHYS), + .irq = MX1FS2_UART2_IRQ, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = 3686400 / 16, + .line = 1, + .type = PORT_16550, + .fifosize = 16 + }, +}; + +void __init +mx1fs2_map_io(void) +{ + imx_map_io(); + iotable_init(mx1fs2_io_desc, ARRAY_SIZE(mx1fs2_io_desc)); + + early_serial_setup(&mx1fs2_serial_ports[0]); + early_serial_setup(&mx1fs2_serial_ports[1]); +} + +static void mx1fs2_lcd_power(int on) +{ + if(on) + DR(3) |= 0x00001000; + else + DR(3) &= ~0x00001000; +} +//#define EXPERIMENTAL +#ifdef EXPERIMENTAL +static struct imxfb_mach_info mx1fs2_fb_info __initdata = { + .pixclock = 62500, .bpp = 8, + .xres = 320, .yres = 240, + + .hsync_len = 2, .vsync_len = 2, + .left_margin = 2, .upper_margin = 2, + .right_margin = 2, .lower_margin = 2, + + .pcr = PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_8 | PCR_PCD(3) | PCR_END_BYTE_SWAP, + .pwmr = PWMR_SCR0 | PWMR_CC_EN | PWMR_PW(0x70), + .lscr1 = 0x04000373, /* reset default */ + + .lcd_power = mx1fs2_lcd_power, +}; +#else +static struct imxfb_mach_info mx1fs2_fb_info __initdata = { + .pixclock = 62500, .bpp = 16, + .xres = 320, .yres = 240, + + .hsync_len = 2, .vsync_len = 2, + .left_margin = 0, .upper_margin = 0, + .right_margin = 0, .lower_margin = 0, + + .pcr = PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 | PCR_PCD(3), + .pwmr = PWMR_SCR0 | PWMR_CC_EN | PWMR_PW(0x70), + .lscr1 = 0x04000373, /* reset default */ + + .lcd_power = mx1fs2_lcd_power, +}; +#endif + +static int mx1fs2_mmc_card_present(void) +{ + return (SSR(3) & (1<<7) ? 0 : 1); +} + +static struct imxmmc_platform_data mx1fs2_mmc_info = { + .card_present = mx1fs2_mmc_card_present, +}; + +static void __init mx1fs2_init(void) +{ + printk("%s\n",__FUNCTION__); + + UFCR(IMX_UART1_BASE) = 0xa81; + UFCR(IMX_UART2_BASE) = 0xa81; + imx_gpio_mode( 9 | GPIO_IN | GPIO_PORTC ); + imx_gpio_mode( 10 | GPIO_IN | GPIO_PORTC ); + + /* mmc card detect and write protect */ + imx_gpio_mode( 7 | GPIO_IN | GPIO_PORTD | GPIO_PUEN | GPIO_GPIO ); + imx_gpio_mode( 10 | GPIO_IN | GPIO_PORTD | GPIO_PUEN | GPIO_GPIO ); + imx_set_mmc_info(&mx1fs2_mmc_info); + + set_irq_type( MX1FS2_UART1_IRQ, __IRQT_HIGHLVL); + set_irq_type( MX1FS2_UART2_IRQ, __IRQT_HIGHLVL); + + set_imx_fb_info(&mx1fs2_fb_info); + + /* output enable for the LCD display */ + mx1fs2_lcd_power(0); + imx_gpio_mode(GPIO_PORTD | GPIO_OUT | GPIO_GPIO | 12); + + return; +} + +MACHINE_START(MX1FS2, "viasys mx1fs2") + MAINTAINER("Sascha Hauer") + BOOT_MEM(0x08000000, 0x00200000, 0xe0200000) + BOOT_PARAMS(0x08000100) + MAPIO(mx1fs2_map_io) + INITIRQ(imx_init_irq) + .timer = &imx_timer, + INIT_MACHINE(mx1fs2_init) +MACHINE_END Index: arch/arm/mach-imx/leds-scb9328.c =================================================================== --- a/arch/arm/mach-imx/leds-scb9328.c (revision 0) +++ b/arch/arm/mach-imx/leds-scb9328.c (revision 490) @@ -0,0 +1,52 @@ +/* + * linux/arch/arm/mach-imx/leds-scb9328.c + * + * Copyright (c) 2004 Sascha Hauer + * + * Original (leds-footbridge.c) by Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "leds.h" + +static int timer_led = 0; + +void +scb9328_leds_event(led_event_t ledevt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (ledevt) { + case led_idle_start: + scb9328_ledoff(1); + break; + + case led_idle_end: + scb9328_ledon(1); + break; + + case led_timer: + timer_led = !timer_led; + if (timer_led) + scb9328_ledon(2); + else + scb9328_ledoff(2); + break; + default: + break; + } + local_irq_restore(flags); +} Index: arch/arm/mach-imx/leds.c =================================================================== --- a/arch/arm/mach-imx/leds.c (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/leds.c (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -21,10 +21,12 @@ static int __init leds_init(void) { - if (machine_is_mx1ads()) { + if (machine_is_mx1ads()) leds_event = mx1ads_leds_event; - } + if (machine_is_scb9328()) + leds_event = scb9328_leds_event; + return 0; } Index: arch/arm/mach-imx/Makefile =================================================================== --- a/arch/arm/mach-imx/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -9,11 +9,16 @@ obj-y += irq.o time.o dma.o generic.o +obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o + # Specific board support obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o +obj-$(CONFIG_MACH_SCB9328) += scb9328.o +obj-$(CONFIG_MACH_MX1FS2) += mx1fs2.o # Support for blinky lights led-y := leds.o +led-$(CONFIG_MACH_SCB9328) += leds-scb9328.o obj-$(CONFIG_LEDS) += $(led-y) led-$(CONFIG_ARCH_MX1ADS) += leds-mx1ads.o Index: arch/arm/mach-imx/leds.h =================================================================== --- a/arch/arm/mach-imx/leds.h (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/leds.h (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -7,3 +7,4 @@ * */ extern void mx1ads_leds_event(led_event_t evt); +extern void scb9328_leds_event(led_event_t evt); Index: arch/arm/mach-imx/mx1ads.c =================================================================== --- a/arch/arm/mach-imx/mx1ads.c (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/mach-imx/mx1ads.c (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -27,6 +27,8 @@ #include #include "generic.h" #include +#include +#include static struct resource mx1ads_resources[] = { [0] = { @@ -51,12 +53,68 @@ &mx1ads_device, }; +static void mx1ads_lcd_power(int on) +{ + if(on) + DR(2) |= 0x00010000; + else + DR(2) &= ~0x00010000; +} + +static struct imxfb_mach_info mx1ads_fb_info __initdata = { + .pixclock = 62500, .bpp = 16, + .xres = 240, .yres = 320, + + .hsync_len = 1, .vsync_len = 1, + .left_margin = 14, .upper_margin = 9, + .right_margin = 6, .lower_margin = 7, + + /* The following settings work with Sharp TFT LQ035Q7DB02 + * For new LCD, we need "active low" pixel polarity. + * If you are using an old LCD, please comment out PCR_PIXPOL. + */ + .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 | PCR_PIXPOL | \ + PCR_ACD_SEL | PCR_ACD(11) | PCR_SHARP | PCR_PCD(2), + + /* For new LCD, we need to enable the constrast control. + * If you are using an old LCD, please comment out PWMR_CC_EN. + */ + .pwmr = PWMR_CLS(169) | PWMR_CC_EN | PWMR_PW(0xB0), + .lscr1 = LSCR1_PS_RISE_DELAY(0) | LSCR1_CLS_RISE_DELAY(9) | + LSCR1_REV_TOGGLE_DELAY(3), + + .lcd_power = mx1ads_lcd_power, +}; + +static int mx1ads_mmc_card_present(void) +{ + return (SSR(1) & (1<<20) ? 0 : 1); +} + +static struct imxmmc_platform_data mx1ads_mmc_info = { + .card_present = mx1ads_mmc_card_present, +}; + static void __init mx1ads_init(void) { #ifdef CONFIG_LEDS imx_gpio_mode(GPIO_PORTA | GPIO_OUT | GPIO_GPIO | 2); #endif + set_imx_fb_info(&mx1ads_fb_info); + + /* mmc card detect */ + imx_gpio_mode( 20 | GPIO_IN | GPIO_PORTB | GPIO_PUEN | GPIO_GPIO ); + /* set SD_DAT_3 to 1, otherwise MMC cards go to SPI mode */ + imx_gpio_mode ( GPIO_PORTB | GPIO_GPIO | GPIO_OUT | 11 ); + DR(1) |= (1<<11); + imx_set_mmc_info(&mx1ads_mmc_info); + +#ifdef CONFIG_FB_IMX + /* This pin enables the Sharp TFT Display */ + imx_gpio_mode(GPIO_PORTC | GPIO_GPIO | GPIO_OUT | GPIO_PF | 16); +#endif + platform_add_devices(devices, ARRAY_SIZE(devices)); } Index: arch/arm/mach-imx/scb9328.c =================================================================== --- a/arch/arm/mach-imx/scb9328.c (revision 0) +++ b/arch/arm/mach-imx/scb9328.c (revision 490) @@ -0,0 +1,230 @@ +/* + * linux/arch/arm/mach-imx/scb9328.c + * + * Copyright (c) 2004 Sascha Hauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + +#define TYPE_NONE 0 +#define TYPE_EVK9328 1 +#define TYPE_EVK9328L 2 + +static int eval_board_type = TYPE_NONE; + +int scb9328_eval_board(void) +{ + return eval_board_type; +} + +static u8 imx_led_shadow = 0; + +/* On the evk9328l eval board we have 4 leds and 4 buttons connected + * PB21 - PB24 -> led0 - led4 + * PB25 - PB27 -> Ta0 - Ta3 + * PA15 -> TA4 + */ + +void scb9328_ledon(int x) +{ + switch(scb9328_eval_board()) { + case TYPE_EVK9328: + imx_led_shadow |= (x); + *((volatile u8 *)(IMX_CS3_VIRT)) = imx_led_shadow; + break; + case TYPE_EVK9328L: + DR(1) |= (x<<21); + break; + default: + break; + } +} + +void scb9328_ledoff(int x) +{ + switch(scb9328_eval_board()) { + case TYPE_EVK9328: + imx_led_shadow &= ~(x); + *((volatile u8 *)(IMX_CS3_VIRT)) = imx_led_shadow; + break; + case TYPE_EVK9328L: + DR(1) &= ~(x<<21); + break; + default: + break; + } +} + +int scb9328_get_buttons(void) +{ + u8 buttons = 0; + + switch(scb9328_eval_board()) { + case TYPE_EVK9328: + buttons = *((volatile u8 *)(IMX_CS3_VIRT)); + printk("%d evk9328", buttons); + break; + case TYPE_EVK9328L: + buttons = (SSR(1) >> 25) & 0x7; /* bits 0-2 */ + buttons |= ((SSR(0) >> 15) & 1) << 3; /* bit 3 */ + buttons = ~buttons & 0xf; /* buttons are inverted */ + printk("%d evk9328l", buttons); + break; + default: + break; + } + return buttons; +} + +void evk9328_init_leds(void) +{ + if( scb9328_eval_board() == TYPE_EVK9328L ) { + GIUS(1) |= (0xf << 21); + DDIR(1) |= (0xf << 21); + OCR2(1) |= (0xff) << ((21 - 16)*2); + scb9328_ledoff(0xf); + + GIUS(1) |= (0x7 << 25); + DDIR(1) &= ~(0x7 << 25); + ICONFA2(1) &= ~(0x3f << 18); + + GIUS(0) |= (1<<15); + DDIR(0) &= ~(1<<15); + ICONFA2(0) &= ~(0x3); + } +} + +EXPORT_SYMBOL(scb9328_ledon); +EXPORT_SYMBOL(scb9328_ledoff); +EXPORT_SYMBOL(scb9328_get_buttons); + +static struct resource dm9000x_resources[] = { + [0] = { + .start = SCB9328_ETH_VIRT, + .end = (SCB9328_ETH_VIRT + 4), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (SCB9328_ETH_IRQ), + .end = (SCB9328_ETH_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm9000x_device = { + .name = "dmfe", + .id = 0, + .num_resources = ARRAY_SIZE(dm9000x_resources), + .resource = dm9000x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &dm9000x_device, +}; + +static int __init scb9328_init(void) +{ + evk9328_init_leds(); + UFCR(IMX_UART1_BASE) = 0xa81; + UFCR(IMX_UART2_BASE) = 0xa81; + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +subsys_initcall(scb9328_init); + +static int __init scb9328_set_board_type(char *str) +{ + if(strncmp( str+1, "evk9328", 8 ) == 0) { + printk("evk9328 eval board found\n"); + eval_board_type = TYPE_EVK9328; + } + if(strncmp( str+1, "evk9328l", 8 ) == 0) { + printk("evk9328l eval board found\n"); + eval_board_type = TYPE_EVK9328L; + } + return 0; +} +__setup("eval_board",scb9328_set_board_type); + +static struct map_desc scb9328_io_desc[] __initdata = { + /* virtual physical length type */ + {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE}, + {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE}, + {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE}, + {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE}, + {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE}, +}; + +static void __init scb9328_init_irq(void) +{ + imx_init_irq(); + set_irq_type(SCB9328_UART1_IRQ,__IRQT_LOWLVL); +} + +#warning "Some of these serial port entries have only been guessed..." + +static struct uart_port scb9328_serial_ports[2] = { + { + .membase = (char *)(SCB9328_UART1_VIRT), + .mapbase = (unsigned long)(SCB9328_UART1_PHYS), + .irq = SCB9328_UART1_IRQ, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM32, // FIXME + .regshift = 2, // FIXME + .uartclk = 7372800/16, // FIXME: this was BASE_BAUD before + .line = 1, // FIXME + .type = PORT_16550, // FIXME + .fifosize = 16 // FIXME + }, { + .membase = (char *)(SCB9328_UART2_VIRT), + .mapbase = (unsigned long)(SCB9328_UART2_PHYS), + .irq = SCB9328_UART2_IRQ, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM32, // FIXME + .regshift = 2, // FIXME + .uartclk = 7372800/16, // FIXME: this was BASE_BAUD before + .line = 1, // FIXME + .type = PORT_16550, // FIXME + .fifosize = 16 // FIXME + }, +}; + +void __init +scb9328_map_io(void) +{ + imx_map_io(); + iotable_init(scb9328_io_desc, ARRAY_SIZE(scb9328_io_desc)); + + early_serial_setup(&scb9328_serial_ports[0]); + early_serial_setup(&scb9328_serial_ports[1]); +} + +MACHINE_START(SCB9328, "Synertronixx scb9328") + MAINTAINER("Sascha Hauer") + BOOT_MEM(0x08000000, 0x00200000, 0xe0200000) + BOOT_PARAMS(0x08000100) + MAPIO(scb9328_map_io) + INITIRQ(scb9328_init_irq) + .timer = &imx_timer, +MACHINE_END Index: arch/arm/configs/mx1fs2_defconfig =================================================================== --- a/arch/arm/configs/mx1fs2_defconfig (revision 0) +++ b/arch/arm/configs/mx1fs2_defconfig (revision 490) @@ -0,0 +1,728 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.10-imx-svn +# Mon Jan 3 19:27:36 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +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 is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set + +# +# 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 + +# +# 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 is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_IMX=y +# CONFIG_ARCH_H720X is not set + +# +# IMX Implementations +# +CONFIG_MACH_MX1FS2=y +# CONFIG_MACH_SCB9328 is not set +# CONFIG_ARCH_MX1ADS is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# General setup +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_XIP_KERNEL is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +CONFIG_FPE_FASTFPE=y +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_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="" +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=y +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_MX1FS2 is not set +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# 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=y +# 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 is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +# 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 is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_SCB9328 is not set +CONFIG_MTD_MX1FS2=y +# CONFIG_MTD_MX1ADS 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_PARIDE is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y + +# +# 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=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_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_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 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 + +# +# 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 is not set +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 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE 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 is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=m +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM 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=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# 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=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +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=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# 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 is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# 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=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# 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=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_IMX=y +# CONFIG_FB_VIRTUAL is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Misc devices +# + +# +# USB support +# +# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_WBSD is not set +CONFIG_MMC_IMX=y + +# +# 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_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_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 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y Index: arch/arm/configs/scb9328_defconfig =================================================================== --- a/arch/arm/configs/scb9328_defconfig (revision 0) +++ b/arch/arm/configs/scb9328_defconfig (revision 490) @@ -0,0 +1,705 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.10-imx-svn +# Tue Jan 4 11:26:35 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +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 is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set + +# +# 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 + +# +# 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 is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_IMX=y +# CONFIG_ARCH_H720X is not set + +# +# IMX Implementations +# +# CONFIG_MACH_MX1FS2 is not set +CONFIG_MACH_SCB9328=y +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_IMX_SCB9328_EVK9328 is not set +CONFIG_IMX_SCB9328_EVK9328L=y +CONFIG_IMX_SCB9328_FLASH_16MB=y +# CONFIG_IMX_SCB9328_FLASH_32MB is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# General setup +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_XIP_KERNEL is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +CONFIG_FPE_FASTFPE=y +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_PM is not set +CONFIG_PREEMPT=y +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +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=y +# 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 is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA 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 is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SCB9328=y +# CONFIG_MTD_MX1FS2 is not set +# CONFIG_MTD_MX1ADS 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=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y + +# +# 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=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_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_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 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 + +# +# 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 is not set +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=y +# CONFIG_SMC91X is not set +CONFIG_DM9000=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO 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 + +# +# 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 is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_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 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=m +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +CONFIG_I2C_DEBUG_CORE=y +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP 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_DNOTIFY=y +# 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_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# 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_TMPFS_XATTR is not set +# 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 is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# 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 is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS 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 +# +# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# 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_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_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 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y Index: arch/arm/configs/mx1ads_defconfig =================================================================== --- a/arch/arm/configs/mx1ads_defconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/arch/arm/configs/mx1ads_defconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -1,22 +1,26 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.10-imx-svn +# Mon Jan 3 18:57:55 2005 # CONFIG_ARM=y CONFIG_MMU=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y # # General setup # +CONFIG_LOCALVERSION="" CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set @@ -25,16 +29,19 @@ # CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_IOSCHED_NOOP is not set -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set # # Loadable module support @@ -44,6 +51,7 @@ # 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 # @@ -58,6 +66,7 @@ # 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 is not set # CONFIG_ARCH_RPC is not set @@ -66,12 +75,15 @@ # 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_VERSATILE is not set CONFIG_ARCH_IMX=y +# CONFIG_ARCH_H720X is not set # # IMX Implementations # +# CONFIG_MACH_MX1FS2 is not set +# CONFIG_MACH_SCB9328 is not set CONFIG_ARCH_MX1ADS=y # @@ -82,6 +94,7 @@ CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y CONFIG_CPU_TLB_V4WBI=y @@ -97,10 +110,9 @@ # General setup # CONFIG_ISA=y -# CONFIG_ZBOOT_ROM is not set CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -# CONFIG_CPU_FREQ is not set +# CONFIG_XIP_KERNEL is not set # # At least one math emulation must be selected @@ -108,7 +120,6 @@ CONFIG_FPE_NWFPE=y CONFIG_FPE_NWFPE_XP=y CONFIG_FPE_FASTFPE=y -# CONFIG_VFP is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set @@ -116,6 +127,7 @@ # # Generic Driver Options # +CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_PM is not set @@ -155,10 +167,19 @@ # # CONFIG_MTD_CFI is not set # CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set # CONFIG_MTD_RAM is not set CONFIG_MTD_ROM=y # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -170,6 +191,7 @@ # 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 @@ -199,8 +221,19 @@ # 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_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set # +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set @@ -232,6 +265,9 @@ # 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_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -251,8 +287,6 @@ # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set # # QoS and/or fair queueing @@ -285,16 +319,18 @@ # CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_SMC91X is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set # CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set +# CONFIG_CS89x0 is not set +# CONFIG_DM9000 is not set # CONFIG_NET_POCKET is not set # @@ -343,7 +379,6 @@ # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set # # I2O device support @@ -369,7 +404,6 @@ # CONFIG_GAMEPORT is not set CONFIG_SOUND_GAMEPORT=y # CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set # # Input Device Drivers @@ -395,7 +429,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_QIC02_TAPE is not set # # IPMI @@ -408,16 +441,12 @@ # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set CONFIG_RTC=m -# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -448,6 +477,7 @@ # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set @@ -477,6 +507,7 @@ # CONFIG_DEVFS_DEBUG is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -494,6 +525,10 @@ CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 # CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -515,6 +550,7 @@ # CONFIG_EXPORTFS is not set CONFIG_SUNRPC=y # 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 @@ -525,6 +561,7 @@ # Partition Types # # CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y # # Native Language Support @@ -592,30 +629,45 @@ # # USB support # +# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set # +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# # USB Gadget Support # # CONFIG_USB_GADGET is not set # +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# # Kernel hacking # -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set -CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set # # Security options # +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # @@ -629,6 +681,7 @@ # 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_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set @@ -636,7 +689,10 @@ # CONFIG_CRYPTO_AES is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set @@ -645,7 +701,7 @@ # # Library routines # -CONFIG_CRC16=y +CONFIG_CRC_CCITT=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y Index: Makefile =================================================================== --- a/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 10 -EXTRAVERSION = +EXTRAVERSION = -imx1 NAME=Woozy Numbat # *DOCUMENTATION* @@ -190,8 +190,8 @@ # Default value for CROSS_COMPILE is not to prefix executables # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile -ARCH ?= $(SUBARCH) -CROSS_COMPILE ?= +ARCH ?= arm +CROSS_COMPILE ?= arm-softfloat-linux-gnu- # Architecture as present in compile.h UTS_MACHINE := $(ARCH) Index: drivers/serial/Kconfig =================================================================== --- a/drivers/serial/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/serial/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -409,6 +409,29 @@ your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_IMX + bool "IMX serial port support" + depends on ARM && ARCH_IMX + select SERIAL_CORE + help + If you have a machine based on a Motorola IMX CPU you + can enable its onboard serial port by enabling this option. + +config SERIAL_IMX_CONSOLE + bool "Console on IMX serial port" + depends on SERIAL_IMX + select SERIAL_CORE_CONSOLE + help + If you have enabled the serial port on the Motorola IMX + CPU you can make it the console by answering Y to this option. + + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttySMX0". (Try "man bootparam" or see the documentation of + your boot loader (lilo or loadlin) about how to pass options to the + kernel at boot time.) + config SERIAL_SUNCORE bool depends on SPARC32 || SPARC64 Index: drivers/serial/Makefile =================================================================== --- a/drivers/serial/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/serial/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -46,4 +46,4 @@ obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o obj-$(CONFIG_SERIAL_ICOM) += icom.o obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o -obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o \ No newline at end of file +obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o Index: drivers/mtd/maps/mx1fs2.c =================================================================== --- a/drivers/mtd/maps/mx1fs2.c (revision 0) +++ b/drivers/mtd/maps/mx1fs2.c (revision 490) @@ -0,0 +1,129 @@ +/* + * linux/drivers/mtd/maps/mx1fs2.c + * + * Mapping driver for the Viasys Flowscreen 2 platform, + * derived from the innokom.c driver. + * + * Authors: Robert Schwebel, Kai-Uwe Bloem, Nicolas Pitre + * Copyright: (C) 2001 MontaVista Software Inc. + * (C) 2003, 2004 Pengutronix + * (C) 2003 Auerswald GmbH & Co. KG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct map_info mx1fs2_map = { + .name = "Flowscreen 2 Flash", + .bankwidth = 4, + .size = MX1FS2_FLASH_SIZE, + .phys = MX1FS2_FLASH_PHYS, +}; + +static struct mtd_partition mx1fs2_partitions[] = { + { + .name = "U-Boot", + .size = 128*1024, + .offset = 0x00000000, + /* mask_flags: MTD_WRITEABLE force read-only */ + },{ + .name = "U-Boot-Environment", + .size = 128*1024, + .offset = 0x00020000, + },{ + .name = "Start-Logo", + .size = 256*1024, + .offset = 0x00040000, + },{ + .name = "Kernel", + .size = 1536*1024, + .offset = 0x00080000, + },{ + .name = "Root-FS", + .size = 5*1024*1024, + .offset = 0x00200000, + },{ + .name = "User-FS", + .size = 9*1024*1024, + .offset = 0x00700000, + } +}; + +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + +static struct mtd_info *mymtd; +static struct mtd_partition *parsed_parts; + +static int __init init_mx1fs2(void) +{ + struct mtd_partition *parts; + int nb_parts = 0; + char *part_type = "static"; + + printk("mx1fs2: probing flash at 0x%08x\n", MX1FS2_FLASH_PHYS); + mx1fs2_map.virt = ioremap(MX1FS2_FLASH_PHYS, MX1FS2_FLASH_SIZE); + + if (!mx1fs2_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&mx1fs2_map); + + mymtd = do_map_probe("cfi_probe", &mx1fs2_map); + if (!mymtd) { + iounmap((void *)mx1fs2_map.map_priv_1); + return -ENXIO; + } + + /* set partition table */ + parts = mx1fs2_partitions; + part_type = "static"; + nb_parts = NB_OF(mx1fs2_partitions); + + printk(KERN_NOTICE "Using %s partition definition\n", part_type); + add_mtd_partitions(mymtd, parts, nb_parts); + + return 0; +} + +static void __exit cleanup_mx1fs2(void) +{ + if (mymtd) { + del_mtd_partitions(mymtd); + map_destroy(mymtd); + if (parsed_parts) + kfree(parsed_parts); + } + if (mx1fs2_map.map_priv_1) + iounmap((void *)mx1fs2_map.map_priv_1); + return; +} + +module_init(init_mx1fs2); +module_exit(cleanup_mx1fs2); + Index: drivers/mtd/maps/Makefile =================================================================== --- a/drivers/mtd/maps/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/mtd/maps/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -69,3 +69,6 @@ obj-$(CONFIG_MTD_IXP2000) += ixp2000.o obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o obj-$(CONFIG_MTD_DMV182) += dmv182.o +obj-$(CONFIG_MTD_SCB9328) += scb9328.o +obj-$(CONFIG_MTD_MX1FS2) += mx1fs2.o +obj-$(CONFIG_MTD_MX1ADS) += mx1ads.o Index: drivers/mtd/maps/Kconfig =================================================================== --- a/drivers/mtd/maps/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/mtd/maps/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -460,6 +460,18 @@ tristate "CFI Flash device mapped on ARM Integrator/P720T" depends on ARM && MTD_CFI +config MTD_SCB9328 + tristate "CFI Flash device mapped on scb9328 board" + depends on ARM && MTD_CFI + +config MTD_MX1FS2 + tristate "CFI Flash device mapped on mx1fs2 board" + depends on ARM && MTD_CFI + +config MTD_MX1ADS + tristate "Flash device mapped on mx1ads board" + depends on ARM + config MTD_CDB89712 tristate "Cirrus CDB89712 evaluation board mappings" depends on ARM && MTD_CFI && ARCH_CDB89712 Index: drivers/mtd/maps/scb9328.c =================================================================== --- a/drivers/mtd/maps/scb9328.c (revision 0) +++ b/drivers/mtd/maps/scb9328.c (revision 490) @@ -0,0 +1,124 @@ +/* + * $Id: scb9328.c,v 1.2 2004/01/29 17:37:19 sascha Exp $ + * + * Map driver for the Lubbock developer platform. + * + * Author: Sascha Hauer + * Copyright: (C) 2004 Sascha Hauer, Synertronix GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//#define FLASH_ADDR 0x04000000 + +//#define WINDOW_SIZE 16*1024*1024 + +static struct map_info scb9328_map = { + .size = SCB9328_FLASH_SIZE, + .virt = SCB9328_FLASH_BASE, + .phys = SCB9328_FLASH_PHYS, + .name = "scb9328_flash", + .bankwidth = 2 +}; + +static struct mtd_partition scb9328_partitions[] = { + { + .name = "Bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_WRITEABLE /* force read-only */ + },{ + .name = "Bootloader env", + .size = 0x00020000, + .offset = 0x00020000, + },{ + .name = "Kernel", + .size = 0x00100000, + .offset = 0x00040000, + },{ + .name = "Rootfs", + .size = 0x00400000, + .offset = 0x00140000, + },{ + .name = "Filesystem", + .size = MTDPART_SIZ_FULL, + .offset = 0x00540000 + } +}; + +static struct mtd_info *mymtds; +static struct mtd_partition *parsed_parts; +static int nr_parsed_parts; + +static const char *probes[] = { "cmdlinepart", NULL }; + +static int __init init_scb9328(void) +{ + int ret = 0; + + printk("scb9328: probing flash at 0x%08x (%d-bit buswidth)\n", SCB9328_FLASH_PHYS, scb9328_map.bankwidth * 8); + scb9328_map.virt = ioremap(SCB9328_FLASH_PHYS, SCB9328_FLASH_SIZE); + if (!scb9328_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&scb9328_map); + + mymtds = do_map_probe("cfi_probe", &scb9328_map); + + if (!mymtds) { + iounmap((void *)scb9328_map.virt); + if (!ret) + return -EIO; + } + mymtds->owner = THIS_MODULE; + + nr_parsed_parts = parse_mtd_partitions(mymtds, probes, + &parsed_parts, 0); + + if (nr_parsed_parts > 0) { + add_mtd_partitions(mymtds, parsed_parts, nr_parsed_parts); + } else { + printk("Using static partitions on %s\n", scb9328_map.name); + add_mtd_partitions(mymtds, scb9328_partitions, ARRAY_SIZE(scb9328_partitions)); + } + + return 0; +} + +static void __exit cleanup_scb9328(void) +{ + + if (nr_parsed_parts) + del_mtd_partitions(mymtds); + else + del_mtd_device(mymtds); + + map_destroy(mymtds); + iounmap((void *)scb9328_map.virt); + + if (parsed_parts) + kfree(parsed_parts); + +} + +module_init(init_scb9328); +module_exit(cleanup_scb9328); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sascha Hauer "); +MODULE_DESCRIPTION("MTD map driver for scb9328"); Index: drivers/mtd/maps/mx1ads.c =================================================================== --- a/drivers/mtd/maps/mx1ads.c (revision 0) +++ b/drivers/mtd/maps/mx1ads.c (revision 490) @@ -0,0 +1,121 @@ +/* + * linux/drivers/mtd/maps/mx1ads.c + * + * Mapping driver for the Viasys Flowscreen 2 platform, + * derived from the innokom.c driver. + * + * Authors: Robert Schwebel, Kai-Uwe Bloem, Nicolas Pitre + * Copyright: (C) 2001 MontaVista Software Inc. + * (C) 2003, 2004 Pengutronix + * (C) 2003 Auerswald GmbH & Co. KG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct map_info mx1ads_map = { + .name = "mx1ads Flash", + .bankwidth = 4, + .size = MX1ADS_FLASH_SIZE, + .phys = MX1ADS_FLASH_PHYS, +}; + +static struct mtd_partition mx1ads_partitions[] = { + { + .name = "U-Boot", + .size = 1024*1024, + .offset = 0x00000000, + /* mask_flags: MTD_WRITEABLE force read-only */ + },{ + .name = "Kernel", + .size = 1024*1024, + .offset = 0x00100000, + },{ + .name = "Root-FS", + .size = 13*1024*1024, + .offset = 0x00200000, + },{ + .name = "U-Boot-Environment", + .size = 1024*1024, + .offset = 0x00F00000, + } +}; + +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + +static struct mtd_info *mymtd; +static struct mtd_partition *parsed_parts; + +static int __init init_mx1ads(void) +{ + struct mtd_partition *parts; + int nb_parts = 0; + char *part_type = "static"; + + printk("mx1ads: probing flash at 0x%08x\n", MX1ADS_FLASH_PHYS); + mx1ads_map.virt = ioremap(MX1ADS_FLASH_PHYS, MX1ADS_FLASH_SIZE); + + if (!mx1ads_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&mx1ads_map); + + mymtd = do_map_probe("map_rom", &mx1ads_map); + if (!mymtd) { + printk("probing failed\n"); + iounmap((void *)mx1ads_map.map_priv_1); + return -ENXIO; + } + + /* set partition table */ + parts = mx1ads_partitions; + part_type = "static"; + nb_parts = NB_OF(mx1ads_partitions); + + printk(KERN_NOTICE "Using %s partition definition\n", part_type); + add_mtd_partitions(mymtd, parts, nb_parts); + + return 0; +} + +static void __exit cleanup_mx1ads(void) +{ + if (mymtd) { + del_mtd_partitions(mymtd); + map_destroy(mymtd); + if (parsed_parts) + kfree(parsed_parts); + } + if (mx1ads_map.map_priv_1) + iounmap((void *)mx1ads_map.map_priv_1); + return; +} + +module_init(init_mx1ads); +module_exit(cleanup_mx1ads); + Index: drivers/video/imxfb.c =================================================================== --- a/drivers/video/imxfb.c (revision 0) +++ b/drivers/video/imxfb.c (revision 490) @@ -0,0 +1,836 @@ +/* + * linux/drivers/video/imxfb.c + * + * Copyright (C) 2004 Sascha Hauer + * Based on acornfb.c Copyright (C) Russell King. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Complain if VAR is out of range. + */ +#define DEBUG_VAR 1 + +// #define DEBUG 1 + +#include "imxfb.h" + +static struct imxfb_rgb def_rgb_16 = { + .red = { offset: 8, length: 4, }, + .green = { offset: 4, length: 4, }, + .blue = { offset: 0, length: 4, }, + .transp = { offset: 0, length: 0, }, +}; + +static struct imxfb_rgb def_rgb_8 = { + .red = { offset: 0, length: 8, }, + .green = { offset: 0, length: 8, }, + .blue = { offset: 0, length: 8, }, + .transp = { offset: 0, length: 0, }, +}; + +static int imxfb_activate_var(struct fb_var_screeninfo *var, struct imxfb_info *); +static void set_ctrlr_state(struct imxfb_info *fbi, u_int state); + +static inline void imxfb_schedule_work(struct imxfb_info *fbi, u_int state) +{ + unsigned long flags; + + local_irq_save(flags); + /* + * We need to handle two requests being made at the same time. + * There are two important cases: + * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) + * We must perform the unblanking, which will do our REENABLE for us. + * 2. When we are blanking, but immediately unblank before we have + * blanked. We do the "REENABLE" thing here as well, just to be sure. + */ + if (fbi->task_state == C_ENABLE && state == C_REENABLE) + state = (u_int) -1; + if (fbi->task_state == C_DISABLE && state == C_ENABLE) + state = C_REENABLE; + + if (state != (u_int)-1) { + fbi->task_state = state; + schedule_work(&fbi->task); + } + local_irq_restore(flags); +} + +static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + +#define LCDC_PALETTE(x) __REG2(IMX_LCDC_BASE+0x800, (x)<<2) +static int +imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, + u_int trans, struct fb_info *info) +{ + struct imxfb_info *fbi = (struct imxfb_info *)info; + u_int val, ret = 1; + +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) + if (regno < fbi->palette_size) { + val = (CNVT_TOHW(red, 4) << 8) | + (CNVT_TOHW(green,4) << 4) | + CNVT_TOHW(blue, 4); + + LCDC_PALETTE(regno) = val; + ret = 0; + } + return ret; +} + +static int +imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int trans, struct fb_info *info) +{ + struct imxfb_info *fbi = (struct imxfb_info *)info; + unsigned int val; + int ret = 1; + + /* + * If inverse mode was selected, invert all the colours + * rather than the register number. The register number + * is what you poke into the framebuffer to produce the + * colour you requested. + */ + if (fbi->cmap_inverse) { + red = 0xffff - red; + green = 0xffff - green; + blue = 0xffff - blue; + } + + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no mater what visual we are using. + */ + if (fbi->fb.var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + + switch (fbi->fb.fix.visual) { + case FB_VISUAL_TRUECOLOR: + /* + * 12 or 16-bit True Colour. We encode the RGB value + * according to the RGB bitfield information. + */ + if (regno < 16) { + u32 *pal = fbi->fb.pseudo_palette; + + val = chan_to_field(red, &fbi->fb.var.red); + val |= chan_to_field(green, &fbi->fb.var.green); + val |= chan_to_field(blue, &fbi->fb.var.blue); + + pal[regno] = val; + ret = 0; + } + break; + + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + ret = imxfb_setpalettereg(regno, red, green, blue, trans, info); + break; + } + + return ret; +} + +/* + * imxfb_check_var(): + * Round up in the following order: bits_per_pixel, xres, + * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, + * bitfields, horizontal timing, vertical timing. + */ +static int +imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct imxfb_info *fbi = (struct imxfb_info *)info; + int rgbidx; + + if (var->xres < MIN_XRES) + var->xres = MIN_XRES; + if (var->yres < MIN_YRES) + var->yres = MIN_YRES; + if (var->xres > fbi->max_xres) + var->xres = fbi->max_xres; + if (var->yres > fbi->max_yres) + var->yres = fbi->max_yres; + var->xres_virtual = max(var->xres_virtual, var->xres); + var->yres_virtual = max(var->yres_virtual, var->yres); + + pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); + switch (var->bits_per_pixel) { + case 16: + rgbidx = RGB_16; + break; + case 8: + rgbidx = RGB_8; + break; + default: + return -EINVAL; + } + + /* + * Copy the RGB parameters for this display + * from the machine specific parameters. + */ + var->red = fbi->rgb[rgbidx]->red; + var->green = fbi->rgb[rgbidx]->green; + var->blue = fbi->rgb[rgbidx]->blue; + var->transp = fbi->rgb[rgbidx]->transp; + + pr_debug("RGBT length = %d:%d:%d:%d\n", + var->red.length, var->green.length, var->blue.length, + var->transp.length); + + pr_debug("RGBT offset = %d:%d:%d:%d\n", + var->red.offset, var->green.offset, var->blue.offset, + var->transp.offset); + + return 0; +} + +/* + * imxfb_set_par(): + * Set the user defined part of the display for the specified console + */ +static int imxfb_set_par(struct fb_info *info) +{ + struct imxfb_info *fbi = (struct imxfb_info *)info; + struct fb_var_screeninfo *var = &info->var; + + pr_debug("set_par\n"); + + if (var->bits_per_pixel == 16) + fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; + else if (!fbi->cmap_static) + fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; + else { + /* + * Some people have weird ideas about wanting static + * pseudocolor maps. I suspect their user space + * applications are broken. + */ + fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; + } + + fbi->fb.fix.line_length = var->xres_virtual * + var->bits_per_pixel / 8; + fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; + + imxfb_activate_var(var, fbi); + + return 0; +} + +/* + * Formal definition of the VESA spec: + * On + * This refers to the state of the display when it is in full operation + * Stand-By + * This defines an optional operating state of minimal power reduction with + * the shortest recovery time + * Suspend + * This refers to a level of power management in which substantial power + * reduction is achieved by the display. The display can have a longer + * recovery time from this state than from the Stand-by state + * Off + * This indicates that the display is consuming the lowest level of power + * and is non-operational. Recovery from this state may optionally require + * the user to manually power on the monitor + * + * Now, the fbdev driver adds an additional state, (blank), where they + * turn off the video (maybe by colormap tricks), but don't mess with the + * video itself: think of it semantically between on and Stand-By. + * + * So here's what we should do in our fbdev blank routine: + * + * VESA_NO_BLANKING (mode 0) Video on, front/back light on + * VESA_VSYNC_SUSPEND (mode 1) Video on, front/back light off + * VESA_HSYNC_SUSPEND (mode 2) Video on, front/back light off + * VESA_POWERDOWN (mode 3) Video off, front/back light off + * + * This will match the matrox implementation. + */ +/* + * imxfb_blank(): + * Blank the display by setting all palette values to zero. Note, the + * 12 and 16 bpp modes don't really use the palette, so this will not + * blank the display in all modes. + */ +static int imxfb_blank(int blank, struct fb_info *info) +{ + struct imxfb_info *fbi = (struct imxfb_info *)info; + int i; + + pr_debug("imxfb_blank: blank=%d\n", blank); + + switch (blank) { + case VESA_POWERDOWN: + case VESA_VSYNC_SUSPEND: + case VESA_HSYNC_SUSPEND: + if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || + fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) + for (i = 0; i < fbi->palette_size; i++) + imxfb_setpalettereg(i, 0, 0, 0, 0, info); + imxfb_schedule_work(fbi, C_DISABLE); + break; + + case VESA_NO_BLANKING: + if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || + fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) + fb_set_cmap(&fbi->fb.cmap, info); + imxfb_schedule_work(fbi, C_ENABLE); + } + return 0; +} + +static struct fb_ops imxfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = imxfb_check_var, + .fb_set_par = imxfb_set_par, + .fb_setcolreg = imxfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_blank = imxfb_blank, + .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */ +}; + +/* + * imxfb_activate_var(): + * Configures LCD Controller based on entries in var parameter. Settings are + * only written to the controller if changes were made. + */ +static int imxfb_activate_var(struct fb_var_screeninfo *var, struct imxfb_info *fbi) +{ + pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", + var->xres, var->hsync_len, + var->left_margin, var->right_margin); + pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n", + var->yres, var->vsync_len, + var->upper_margin, var->lower_margin); + +#if DEBUG_VAR + if (var->xres < 16 || var->xres > 1024) + printk(KERN_ERR "%s: invalid xres %d\n", + fbi->fb.fix.id, var->xres); + if (var->hsync_len < 1 || var->hsync_len > 64) + printk(KERN_ERR "%s: invalid hsync_len %d\n", + fbi->fb.fix.id, var->hsync_len); + if (var->left_margin > 255) + printk(KERN_ERR "%s: invalid left_margin %d\n", + fbi->fb.fix.id, var->left_margin); + if (var->right_margin > 255) + printk(KERN_ERR "%s: invalid right_margin %d\n", + fbi->fb.fix.id, var->right_margin); + if (var->yres < 1 || var->yres > 511) + printk(KERN_ERR "%s: invalid yres %d\n", + fbi->fb.fix.id, var->yres); + if (var->vsync_len > 100) + printk(KERN_ERR "%s: invalid vsync_len %d\n", + fbi->fb.fix.id, var->vsync_len); + if (var->upper_margin > 63) + printk(KERN_ERR "%s: invalid upper_margin %d\n", + fbi->fb.fix.id, var->upper_margin); + if (var->lower_margin > 255) + printk(KERN_ERR "%s: invalid lower_margin %d\n", + fbi->fb.fix.id, var->lower_margin); +#endif + + LCDC_HCR = HCR_H_WIDTH(var->hsync_len) | + HCR_H_WAIT_1(var->left_margin) | + HCR_H_WAIT_2(var->right_margin); + + LCDC_VCR = VCR_V_WIDTH(var->vsync_len) | + VCR_V_WAIT_1(var->upper_margin) | + VCR_V_WAIT_2(var->lower_margin); + + LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres); + LCDC_PCR = fbi->pcr; + LCDC_PWMR = fbi->pwmr; + LCDC_LSCR1 = fbi->lscr1; + + imxfb_schedule_work(fbi, C_REENABLE); + + return 0; +} + +static void imxfb_setup_gpio(struct imxfb_info *fbi) +{ + int width; + + LCDC_RMCR &= ~(RMCR_LCDC_EN | RMCR_SELF_REF); + + if( fbi->pcr & PCR_TFT ) + width = 16; + else + width = 1 << ((fbi->pcr >> 28) & 0x3); + + switch(width) { + case 16: + imx_gpio_mode(PD30_PF_LD15); + imx_gpio_mode(PD29_PF_LD14); + imx_gpio_mode(PD28_PF_LD13); + imx_gpio_mode(PD27_PF_LD12); + imx_gpio_mode(PD26_PF_LD11); + imx_gpio_mode(PD25_PF_LD10); + imx_gpio_mode(PD24_PF_LD9); + imx_gpio_mode(PD23_PF_LD8); + case 8: + imx_gpio_mode(PD22_PF_LD7); + imx_gpio_mode(PD21_PF_LD6); + imx_gpio_mode(PD20_PF_LD5); + imx_gpio_mode(PD19_PF_LD4); + case 4: + imx_gpio_mode(PD18_PF_LD3); + imx_gpio_mode(PD17_PF_LD2); + case 2: + imx_gpio_mode(PD16_PF_LD1); + case 1: + imx_gpio_mode(PD15_PF_LD0); + } + + /* initialize GPIOs */ + imx_gpio_mode(PD6_PF_LSCLK); + imx_gpio_mode(PD10_PF_SPL_SPR); + imx_gpio_mode(PD11_PF_CONTRAST); + imx_gpio_mode(PD14_PF_FLM_VSYNC); + imx_gpio_mode(PD13_PF_LP_HSYNC); + imx_gpio_mode(PD7_PF_REV); + imx_gpio_mode(PD8_PF_CLS); + imx_gpio_mode(PD9_PF_PS); + +#ifndef CONFIG_MACH_MX1FS2 + /* on mx1fs2 this pin is used to (de)activate the display, so we need + * it as a normal gpio + */ + imx_gpio_mode(PD12_PF_ACD_OE); +#endif + +} + +static void imxfb_enable_controller(struct imxfb_info *fbi) +{ + pr_debug("Enabling LCD controller\n"); + + /* initialize LCDC */ + LCDC_RMCR &= ~RMCR_LCDC_EN; /* just to be safe... */ + + LCDC_SSA = fbi->screen_dma; + /* physical screen start address */ + LCDC_VPW = VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4); + + LCDC_POS = 0x00000000; /* panning offset 0 (0 pixel offset) */ + + /* disable hardware cursor */ + LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1); + + /* fixed burst length (see erratum 11) */ + LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2); + + LCDC_RMCR = RMCR_LCDC_EN; +} + +static void imxfb_disable_controller(struct imxfb_info *fbi) +{ + DECLARE_WAITQUEUE(wait, current); + pr_debug("Disabling LCD controller\n"); + + add_wait_queue(&fbi->ctrlr_wait, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + + /* LCD off */ + if(fbi->lcd_power) + fbi->lcd_power(0); + + LCDC_RMCR = 0; + + schedule_timeout(20 * HZ / 1000); + remove_wait_queue(&fbi->ctrlr_wait, &wait); +} + +/* + * This function must be called from task context only, since it will + * sleep when disabling the LCD controller, or if we get two contending + * processes trying to alter state. + */ +static void set_ctrlr_state(struct imxfb_info *fbi, u_int state) +{ + u_int old_state; + + down(&fbi->ctrlr_sem); + + old_state = fbi->state; + + /* + * Hack around fbcon initialisation. + */ + if (old_state == C_STARTUP && state == C_REENABLE) + state = C_ENABLE; + + switch (state) { + case C_DISABLE_CLKCHANGE: + /* + * Disable controller for clock change. If the + * controller is already disabled, then do nothing. + */ + if (old_state != C_DISABLE && old_state != C_DISABLE_PM) { + fbi->state = state; + imxfb_disable_controller(fbi); + } + break; + + case C_DISABLE_PM: + case C_DISABLE: + /* + * Disable controller + */ + if (old_state != C_DISABLE) { + fbi->state = state; + + if(fbi->backlight_power) + fbi->backlight_power(0); + if(fbi->lcd_power) + fbi->lcd_power(0); + if (old_state != C_DISABLE_CLKCHANGE) + imxfb_disable_controller(fbi); + } + break; + + case C_ENABLE_CLKCHANGE: + /* + * Enable the controller after clock change. Only + * do this if we were disabled for the clock change. + */ + if (old_state == C_DISABLE_CLKCHANGE) { + fbi->state = C_ENABLE; + imxfb_enable_controller(fbi); + } + break; + + case C_REENABLE: + /* + * Re-enable the controller only if it was already + * enabled. This is so we reprogram the control + * registers. + */ + if (old_state == C_ENABLE) { + imxfb_disable_controller(fbi); + imxfb_setup_gpio(fbi); + imxfb_enable_controller(fbi); + } + break; + + case C_ENABLE_PM: + /* + * Re-enable the controller after PM. This is not + * perfect - think about the case where we were doing + * a clock change, and we suspended half-way through. + */ + if (old_state != C_DISABLE_PM) + break; + /* fall through */ + + case C_ENABLE: + /* + * Power up the LCD screen, enable controller, and + * turn on the backlight. + */ + if (old_state != C_ENABLE) { + fbi->state = C_ENABLE; + imxfb_setup_gpio(fbi); + imxfb_enable_controller(fbi); + if(fbi->backlight_power) + fbi->backlight_power(1); + if(fbi->lcd_power) + fbi->lcd_power(1); + } + break; + } + up(&fbi->ctrlr_sem); +} + +/* + * Our LCD controller task (which is called when we blank or unblank) + * via keventd. + */ +static void imxfb_task(void *dummy) +{ + struct imxfb_info *fbi = dummy; + u_int state = xchg(&fbi->task_state, -1); + + set_ctrlr_state(fbi, state); +} + +#ifdef CONFIG_PM +/* + * Power management hooks. Note that we won't be called from IRQ context, + * unlike the blank functions above, so we may sleep. + */ +static int imxfb_suspend(struct device *dev, u32 state, u32 level) +{ + struct imxfb_info *fbi = dev_get_drvdata(dev); + pr_debug("%s\n",__FUNCTION__); + + if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) + set_ctrlr_state(fbi, C_DISABLE_PM); + return 0; +} + +static int imxfb_resume(struct device *dev, u32 level) +{ + struct imxfb_info *fbi = dev_get_drvdata(dev); + pr_debug("%s\n",__FUNCTION__); + + if (level == RESUME_ENABLE) + set_ctrlr_state(fbi, C_ENABLE_PM); + return 0; +} +#else +#define imxfb_suspend NULL +#define imxfb_resume NULL +#endif + +static struct imxfb_info * __init imxfb_init_fbinfo(struct device *dev) +{ + struct imxfb_mach_info *inf = dev->platform_data; + struct imxfb_info *fbi; + + pr_debug("%s\n",__FUNCTION__); + + /* Alloc the imxfb_info and pseudo_palette in one step */ + fbi = kmalloc(sizeof(struct imxfb_info) + sizeof(u32) * 16, + GFP_KERNEL); + if (!fbi) + return NULL; + + memset(fbi, 0, sizeof(struct imxfb_info)); + fbi->dev = dev; + + strcpy(fbi->fb.fix.id, IMX_NAME); + + fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; + fbi->fb.fix.type_aux = 0; + fbi->fb.fix.xpanstep = 0; + fbi->fb.fix.ypanstep = 0; + fbi->fb.fix.ywrapstep = 0; + fbi->fb.fix.accel = FB_ACCEL_NONE; + + fbi->fb.var.nonstd = 0; + fbi->fb.var.activate = FB_ACTIVATE_NOW; + fbi->fb.var.height = -1; + fbi->fb.var.width = -1; + fbi->fb.var.accel_flags = 0; + fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; + + fbi->fb.fbops = &imxfb_ops; + fbi->fb.flags = FBINFO_FLAG_DEFAULT; + fbi->fb.pseudo_palette = (fbi + 1); + + fbi->rgb[RGB_16] = &def_rgb_16; + fbi->rgb[RGB_8] = &def_rgb_8; + + fbi->max_xres = inf->xres; + fbi->fb.var.xres = inf->xres; + fbi->fb.var.xres_virtual = inf->xres; + fbi->max_yres = inf->yres; + fbi->fb.var.yres = inf->yres; + fbi->fb.var.yres_virtual = inf->yres; + fbi->max_bpp = inf->bpp; + fbi->fb.var.bits_per_pixel = inf->bpp; + fbi->fb.var.pixclock = inf->pixclock; + fbi->fb.var.hsync_len = inf->hsync_len; + fbi->fb.var.left_margin = inf->left_margin; + fbi->fb.var.right_margin = inf->right_margin; + fbi->fb.var.vsync_len = inf->vsync_len; + fbi->fb.var.upper_margin = inf->upper_margin; + fbi->fb.var.lower_margin = inf->lower_margin; + fbi->fb.var.sync = inf->sync; + fbi->fb.var.grayscale = inf->cmap_greyscale; + fbi->cmap_inverse = inf->cmap_inverse; + fbi->pcr = inf->pcr; + fbi->lscr1 = inf->lscr1; + fbi->pwmr = inf->pwmr; + fbi->lcd_power = inf->lcd_power; + fbi->backlight_power = inf->backlight_power; + fbi->state = C_STARTUP; + fbi->task_state = (u_char)-1; + fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * + fbi->max_bpp / 8; + + init_waitqueue_head(&fbi->ctrlr_wait); + INIT_WORK(&fbi->task, imxfb_task, fbi); + init_MUTEX(&fbi->ctrlr_sem); + + imxfb_set_par((struct fb_info*)fbi); + imxfb_schedule_work(fbi, C_REENABLE); + + return fbi; +} + +/* + * Allocates the DRAM memory for the frame buffer. This buffer is + * remapped into a non-cached, non-buffered, memory region to + * allow pixel writes to occur without flushing the cache. + * Once this area is remapped, all virtual memory access to the + * video memory should occur at the new region. + */ +static int __init imxfb_map_video_memory(struct imxfb_info *fbi) +{ + fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len); + fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, + &fbi->map_dma,GFP_KERNEL); + + if (fbi->map_cpu) { + fbi->fb.screen_base = fbi->map_cpu; + fbi->screen_cpu = fbi->map_cpu; + fbi->screen_dma = fbi->map_dma; + fbi->fb.fix.smem_start = fbi->screen_dma; + } + + return fbi->map_cpu ? 0 : -ENOMEM; +} + +static int __init imxfb_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct imxfb_info *fbi; + struct imxfb_mach_info *inf; + struct resource *res; + int ret; + + printk("i.MX Framebuffer driver\n"); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + inf = dev->platform_data; + if(!inf) { + dev_err(dev,"No platform_data available\n"); + return -ENOMEM; + } + + fbi = imxfb_init_fbinfo(dev); + if (!fbi) { + ret = -ENOMEM; + goto failed; + } + + res = request_mem_region(res->start, res->end - res->start, "IMXFB"); + if (!res) { + ret = -EBUSY; + goto failed; + } + + ret = imxfb_map_video_memory(fbi); + if (ret) { + dev_err(dev, "Failed to allocate video RAM: %d\n", ret); + ret = -ENOMEM; + goto failed; + } + + /* + * This makes sure that our colour bitfield + * descriptors are correctly initialised. + */ + imxfb_check_var(&fbi->fb.var, &fbi->fb); + + fb_alloc_cmap(&fbi->fb.cmap, 1<fb.var.bits_per_pixel, 0); + + dev_set_drvdata(dev, fbi); + + ret = register_framebuffer(&fbi->fb); + if (ret < 0) { + dev_err(dev, "failed to register framebuffer\n"); + goto failed; + } + + return 0; + +failed: + dev_set_drvdata(dev, NULL); + if (fbi) + kfree(fbi); + release_resource(res); + return ret; +} + +static int imxfb_remove(struct device *dev) +{ + struct imxfb_info *fbi = dev_get_drvdata(dev); + + /* disable LCD controller */ + LCDC_RMCR &= ~RMCR_LCDC_EN; + + unregister_framebuffer(&fbi->fb); + + if (fbi) + kfree(fbi); + + dev_set_drvdata(dev, NULL); + + return 0; +} + +void imxfb_shutdown(struct device * dev) +{ + /* disable LCD Controller */ + LCDC_RMCR &= ~RMCR_LCDC_EN; +} + +static struct device_driver imxfb_driver = { + .name = "imx-fb", + .bus = &platform_bus_type, + .probe = imxfb_probe, + .suspend = imxfb_suspend, + .resume = imxfb_resume, + .remove = imxfb_remove, + .shutdown = imxfb_shutdown, +}; + +int __init imxfb_init(void) +{ + return driver_register(&imxfb_driver); +} + +static void __exit imxfb_cleanup(void) +{ + driver_unregister(&imxfb_driver); +} + +module_init(imxfb_init); +module_exit(imxfb_cleanup); + +MODULE_DESCRIPTION("Motorola i.MX framebuffer driver"); +MODULE_AUTHOR("Sascha Hauer, Pengutronix"); +MODULE_LICENSE("GPL"); Index: drivers/video/imxfb.h =================================================================== --- a/drivers/video/imxfb.h (revision 0) +++ b/drivers/video/imxfb.h (revision 490) @@ -0,0 +1,94 @@ +/* + * linux/drivers/video/imxfb.h + * -- Motorola i.MX frame buffer driver + * + * Copyright (C) 2004 S.Hauer, Pengutronix + * + * Copyright (C) 1999 Eric A. Thomas + * Based on acornfb.c Copyright (C) Russell King. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * These are the bitfields for each + * display depth that we support. + */ +struct imxfb_rgb { + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; +}; + +#define RGB_16 (0) +#define RGB_8 (1) +#define NR_RGB 2 + +struct imxfb_info { + struct fb_info fb; + struct device *dev; + struct imxfb_rgb *rgb[NR_RGB]; + + u_int max_bpp; + u_int max_xres; + u_int max_yres; + + /* + * These are the addresses we mapped + * the framebuffer memory region to. + */ + dma_addr_t map_dma; + u_char * map_cpu; + u_int map_size; + + u_char * screen_cpu; + dma_addr_t screen_dma; + u_int palette_size; + + dma_addr_t dbar1; + dma_addr_t dbar2; + + u_int pcr; + u_int pwmr; + u_int lscr1; + u_int cmap_inverse:1, + cmap_static:1, + unused:30; + + volatile u_char state; + volatile u_char task_state; + struct semaphore ctrlr_sem; + wait_queue_head_t ctrlr_wait; + struct work_struct task; + + void (*lcd_power)(int); + void (*backlight_power)(int); +#ifdef CONFIG_CPU_FREQ + struct notifier_block freq_transition; + struct notifier_block freq_policy; +#endif +}; + +/* + * These are the actions for set_ctrlr_state + */ +#define C_DISABLE (0) +#define C_ENABLE (1) +#define C_DISABLE_CLKCHANGE (2) +#define C_ENABLE_CLKCHANGE (3) +#define C_REENABLE (4) +#define C_DISABLE_PM (5) +#define C_ENABLE_PM (6) +#define C_STARTUP (7) + +#define IMX_NAME "IMX" + +/* + * Minimum X and Y resolutions + */ +#define MIN_XRES 64 +#define MIN_YRES 64 + Index: drivers/video/Makefile =================================================================== --- a/drivers/video/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/video/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -94,6 +94,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_PXA) += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o +obj-$(CONFIG_FB_IMX) += imxfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o Index: drivers/video/Kconfig =================================================================== --- a/drivers/video/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/video/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -133,6 +133,10 @@ If you plan to use the LCD display with your SA-1100 system, say Y here. +config FB_IMX + tristate "Motorola i.MX LCD support" + depends on FB && ARM && ARCH_IMX + config FB_CYBER2000 tristate "CyberPro 2000/2010/5000 support" depends on FB && PCI && (BROKEN || !SPARC64) Index: drivers/mmc/Kconfig =================================================================== --- a/drivers/mmc/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/mmc/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -60,4 +60,14 @@ If unsure, say N. +config MMC_IMX + tristate "Motorola i.MX Multimedia Card Interface support" + depends on ARCH_IMX && MMC + help + This selects the Motorola i.MX Multimedia card Interface. + If you have a i.MX platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + endmenu Index: drivers/mmc/imxmmc.h =================================================================== --- a/drivers/mmc/imxmmc.h (revision 0) +++ b/drivers/mmc/imxmmc.h (revision 490) @@ -0,0 +1,67 @@ + +# define __REG16(x) (*((volatile u16 *)IO_ADDRESS(x))) + +#define MMC_STR_STP_CLK __REG16(IMX_MMC_BASE + 0x00) +#define MMC_STATUS __REG16(IMX_MMC_BASE + 0x04) +#define MMC_CLK_RATE __REG16(IMX_MMC_BASE + 0x08) +#define MMC_CMD_DAT_CONT __REG16(IMX_MMC_BASE + 0x0C) +#define MMC_RES_TO __REG16(IMX_MMC_BASE + 0x10) +#define MMC_READ_TO __REG16(IMX_MMC_BASE + 0x14) +#define MMC_BLK_LEN __REG16(IMX_MMC_BASE + 0x18) +#define MMC_NOB __REG16(IMX_MMC_BASE + 0x1C) +#define MMC_REV_NO __REG16(IMX_MMC_BASE + 0x20) +#define MMC_INT_MASK __REG16(IMX_MMC_BASE + 0x24) +#define MMC_CMD __REG16(IMX_MMC_BASE + 0x28) +#define MMC_ARGH __REG16(IMX_MMC_BASE + 0x2C) +#define MMC_ARGL __REG16(IMX_MMC_BASE + 0x30) +#define MMC_RES_FIFO __REG16(IMX_MMC_BASE + 0x34) +#define MMC_BUFFER_ACCESS __REG16(IMX_MMC_BASE + 0x38) +#define MMC_BUFFER_ACCESS_OFS 0x38 + + +#define STR_STP_CLK_ENDIAN (1<<5) +#define STR_STP_CLK_RESET (1<<3) +#define STR_STP_CLK_ENABLE (1<<2) +#define STR_STP_CLK_START_CLK (1<<1) +#define STR_STP_CLK_STOP_CLK (1<<0) +#define STATUS_CARD_PRESENCE (1<<15) +#define STATUS_SDIO_INT_ACTIVE (1<<14) +#define STATUS_END_CMD_RESP (1<<13) +#define STATUS_WRITE_OP_DONE (1<<12) +#define STATUS_DATA_TRANS_DONE (1<<11) +#define STATUS_WR_CRC_ERROR_CODE_MASK (3<<10) +#define STATUS_CARD_BUS_CLK_RUN (1<<8) +#define STATUS_APPL_BUFF_FF (1<<7) +#define STATUS_APPL_BUFF_FE (1<<6) +#define STATUS_RESP_CRC_ERR (1<<5) +#define STATUS_CRC_READ_ERR (1<<3) +#define STATUS_CRC_WRITE_ERR (1<<2) +#define STATUS_TIME_OUT_RESP (1<<1) +#define STATUS_TIME_OUT_READ (1<<0) +#define STATUS_ERR_MASK 0x3f +#define CLK_RATE_PRESCALER(x) ((x) & 0x7) +#define CLK_RATE_CLK_RATE(x) (((x) & 0x7) << 3) +#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1<<12) +#define CMD_DAT_CONT_STOP_READWAIT (1<<11) +#define CMD_DAT_CONT_START_READWAIT (1<<10) +#define CMD_DAT_CONT_BUS_WIDTH_1 (0<<8) +#define CMD_DAT_CONT_BUS_WIDTH_4 (2<<8) +#define CMD_DAT_CONT_INIT (1<<7) +#define CMD_DAT_CONT_BUSY (1<<6) +#define CMD_DAT_CONT_STREAM_BLOCK (1<<5) +#define CMD_DAT_CONT_WRITE (1<<4) +#define CMD_DAT_CONT_DATA_ENABLE (1<<3) +#define CMD_DAT_CONT_RESPONSE_FORMAT_R1 (1) +#define CMD_DAT_CONT_RESPONSE_FORMAT_R2 (2) +#define CMD_DAT_CONT_RESPONSE_FORMAT_R3 (3) +#define CMD_DAT_CONT_RESPONSE_FORMAT_R4 (4) +#define CMD_DAT_CONT_RESPONSE_FORMAT_R5 (5) +#define CMD_DAT_CONT_RESPONSE_FORMAT_R6 (6) +#define INT_MASK_AUTO_CARD_DETECT (1<<6) +#define INT_MASK_DAT0_EN (1<<5) +#define INT_MASK_SDIO (1<<4) +#define INT_MASK_BUF_READY (1<<3) +#define INT_MASK_END_CMD_RES (1<<2) +#define INT_MASK_WRITE_OP_DONE (1<<1) +#define INT_MASK_DATA_TRAN (1<<0) +#define INT_ALL (0x7f) Index: drivers/mmc/imxmmc.c =================================================================== --- a/drivers/mmc/imxmmc.c (revision 0) +++ b/drivers/mmc/imxmmc.c (revision 490) @@ -0,0 +1,590 @@ +/* + * linux/drivers/mmc/imxmmc.c - Motorola i.MX MMCI driver + * + * Copyright (C) 2004 Sascha Hauer, Pengutronix + * + * derived from pxamci.c by Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "imxmmc.h" + +#define DRIVER_NAME "IMXMMC" + +#ifdef CONFIG_MMC_DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +struct imxmci_host { + struct mmc_host *mmc; + spinlock_t lock; + struct resource *res; + int irq; + int dma; + unsigned int clkrt; + unsigned int cmdat; + unsigned int imask; + unsigned int power_mode; + unsigned int present; + struct imxmmc_platform_data *pdata; + + struct mmc_request *req; + struct mmc_command *cmd; + struct mmc_data *data; + + struct timer_list timer; + + dma_addr_t dma_buf; + unsigned int dma_size; + unsigned int dma_dir; +}; + +static void imxmci_stop_clock(struct imxmci_host *host) +{ + int i; + while(1) { + MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK; + i = 0; + while( (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) && (i++ < 100)); + + if ( !(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) ) + break; + } +} + +static void imxmci_start_clock(struct imxmci_host *host) +{ + int i; + while(1) { + MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; + i = 0; + while( !(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) && (i++ < 100)); + + if ( MMC_STATUS & STATUS_CARD_BUS_CLK_RUN ) + break; + } +} + +static void imxmci_softreset(void) +{ + /* reset sequence */ + MMC_STR_STP_CLK = 0x8; + MMC_STR_STP_CLK = 0xD; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + MMC_STR_STP_CLK = 0x5; + + MMC_RES_TO = 0xff; + MMC_BLK_LEN = 512; + MMC_NOB = 1; +} + +static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) +{ + unsigned int nob = data->blocks; + unsigned int ccr = CCR_REN; + + if (data->flags & MMC_DATA_STREAM) + nob = 0xffff; + + host->data = data; + + MMC_NOB = nob; + MMC_BLK_LEN = 1 << data->blksz_bits; + + if (data->flags & MMC_DATA_READ) { + host->dma_dir = DMA_FROM_DEVICE; + ccr |= CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_DSIZ_32; + } else { + host->dma_dir = DMA_TO_DEVICE; + ccr |= CCR_DMOD_FIFO | CCR_SSIZ_32 | CCR_DSIZ_16; + } + + host->dma_size = data->blocks << data->blksz_bits; + host->dma_buf = dma_map_single(mmc_dev(host->mmc), data->req->buffer, + host->dma_size, host->dma_dir); + + if (data->flags & MMC_DATA_READ) { + SAR(host->dma) = host->res->start + MMC_BUFFER_ACCESS_OFS; + DAR(host->dma) = host->dma_buf; + } else { + SAR(host->dma) = host->dma_buf; + DAR(host->dma) = host->res->start + MMC_BUFFER_ACCESS_OFS; + } + + BLR(host->dma) = 0x08; + + CNTR(host->dma) = host->dma_size; + CCR(host->dma) = ccr; + RSSR(host->dma) = DMA_REQ_SDHC; + + /* finally start DMA engine */ + CCR(host->dma) |= CCR_CEN; +} + +static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat) +{ + WARN_ON(host->cmd != NULL); + host->cmd = cmd; + + if (cmd->flags & MMC_RSP_BUSY) + cmdat |= CMD_DAT_CONT_BUSY; + + switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) { + case MMC_RSP_SHORT | MMC_RSP_CRC: + cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1; + break; + case MMC_RSP_SHORT: + cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3; + break; + case MMC_RSP_LONG | MMC_RSP_CRC: + cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R2; + break; + default: + break; + } + + if ( cmd->opcode == MMC_GO_IDLE_STATE ) + cmdat |= CMD_DAT_CONT_INIT; /* This command needs init */ + + MMC_CMD = cmd->opcode; + MMC_ARGH = cmd->arg >> 16; + MMC_ARGL = cmd->arg & 0xffff; + MMC_CMD_DAT_CONT = cmdat; + + imxmci_start_clock(host); +} + +static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request *req) +{ + host->req = NULL; + host->cmd = NULL; + host->data = NULL; + mmc_request_done(host->mmc, req); +} + +static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) +{ + struct mmc_command *cmd = host->cmd; + int i; + u32 a,b,c; + + if (!cmd) + return 0; + + host->cmd = NULL; + + if (stat & STATUS_TIME_OUT_RESP) { + DBG("%s: CMD TIMEOUT\n",DRIVER_NAME); + cmd->error = MMC_ERR_TIMEOUT; + } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) { + DBG("%s: cmd crc error\n",DRIVER_NAME); + cmd->error = MMC_ERR_BADCRC; + } + + switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) { + case MMC_RSP_SHORT | MMC_RSP_CRC: + a = MMC_RES_FIFO & 0xffff; + b = MMC_RES_FIFO & 0xffff; + c = MMC_RES_FIFO & 0xffff; + cmd->resp[0] = a<<24 | b<<8 | c>>8; + break; + case MMC_RSP_SHORT: + a = MMC_RES_FIFO & 0xffff; + b = MMC_RES_FIFO & 0xffff; + c = MMC_RES_FIFO & 0xffff; + cmd->resp[0] = a<<24 | b<<8 | c>>8; + break; + case MMC_RSP_LONG | MMC_RSP_CRC: + for (i = 0; i < 4; i++) { + u32 a = MMC_RES_FIFO & 0xffff; + u32 b = MMC_RES_FIFO & 0xffff; + cmd->resp[i] = a<<16 | b; + } + break; + default: + break; + } + + DBG("%s: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",DRIVER_NAME,cmd->resp[0], + cmd->resp[1],cmd->resp[2],cmd->resp[3]); + + + if (host->data && cmd->error == MMC_ERR_NONE) { + /* nothing */ + } else { + imxmci_stop_clock(host); + imxmci_finish_request(host, host->req); + } + + return 1; +} + +static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) +{ + struct mmc_data *data = host->data; + + CCR(host->dma) &= ~CCR_CEN; + + if (!data) + return 0; + + dma_unmap_single(mmc_dev(host->mmc), host->dma_buf, host->dma_size, + host->dma_dir); + + if ( MMC_STATUS & STATUS_ERR_MASK ) { + DBG("%s: request failed. status: 0x%08x\n",DRIVER_NAME,MMC_STATUS); + } + + host->data = NULL; + data->bytes_xfered = host->dma_size; + + if (host->req->stop && data->error == MMC_ERR_NONE) { + imxmci_stop_clock(host); + imxmci_start_cmd(host, host->req->stop, 0); + } else { + imxmci_finish_request(host, host->req); + } + + return 1; +} + +static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs) +{ + struct imxmci_host *host = devid; + unsigned int status = 0; + int handled = 0,timeout = 10000; + + spin_lock(host->lock); + + status = MMC_STATUS; + + while( !handled && --timeout ) { + if(status & STATUS_END_CMD_RESP) { + imxmci_cmd_done(host, status); + handled = 1; + } + status = MMC_STATUS; + } + + if(!timeout) { + printk("%s: fake interrupt\n",DRIVER_NAME); + handled = 1; + } + + MMC_INT_MASK = host->imask; + + spin_unlock(host->lock); + + return IRQ_RETVAL(handled); +} + +static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req) +{ + struct imxmci_host *host = mmc_priv(mmc); + unsigned int cmdat; + + WARN_ON(host->req != NULL); + + host->req = req; + + cmdat = 0; + + if (req->data) { + imxmci_setup_data(host, req->data); + + cmdat |= CMD_DAT_CONT_DATA_ENABLE; + + if (req->data->flags & MMC_DATA_WRITE) + cmdat |= CMD_DAT_CONT_WRITE; + + if (req->data->flags & MMC_DATA_STREAM) { + cmdat |= CMD_DAT_CONT_STREAM_BLOCK; + } + } + + imxmci_start_cmd(host, req->cmd, cmdat); +} + +#define CLK_RATE 19200000 + +static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct imxmci_host *host = mmc_priv(mmc); + int prescaler; + + DBG("%s: clock %u power %u vdd %u.%02u\n", DRIVER_NAME, + ios->clock, ios->power_mode, ios->vdd / 100, + ios->vdd % 100); + + if ( ios->clock ) { + prescaler = 5; /* 96MHz / 5 = 19.2 MHz */ + unsigned int clk; + + for(clk=0; clk<8; clk++) { + int x; + x = CLK_RATE / (1<clock) + break; + } + + MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */ + + imxmci_stop_clock(host); + MMC_CLK_RATE = (prescaler<<3) | clk; + imxmci_start_clock(host); + + DBG("%s:MMC_CLK_RATE: 0x%08x\n",DRIVER_NAME,MMC_CLK_RATE); + } else { + imxmci_stop_clock(host); + } +} + +static struct mmc_host_ops imxmci_ops = { + .request = imxmci_request, + .set_ios = imxmci_set_ios, +}; + +static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) + if (dev->resource[i].flags == mask && nr-- == 0) + return &dev->resource[i]; + return NULL; +} + +static int platform_device_irq(struct platform_device *dev, int nr) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) + if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0) + return dev->resource[i].start; + return NO_IRQ; +} + +static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs) +{ + struct imxmci_host *host = devid; + u32 status; + + do { + status = MMC_STATUS; + } while( !(status & STATUS_DATA_TRANS_DONE)); + + imxmci_data_done(host, status); + MMC_INT_MASK = host->imask; +} + +static void imxmci_check_status(unsigned long data) +{ + struct imxmci_host *host = (struct imxmci_host *)data; + + if( host->pdata->card_present() != host->present ) { + host->present ^= 1; + printk(KERN_INFO "%s: card %s\n",DRIVER_NAME, + host->present ? "inserted" : "removed"); + mmc_detect_change(host->mmc); + } + mod_timer(&host->timer, jiffies + (HZ>>1)); +} + +static int imxmci_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct mmc_host *mmc; + struct imxmci_host *host = NULL; + struct resource *r; + int ret = 0, irq; + + printk("i.MX mmc driver\n"); + + r = platform_device_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_device_irq(pdev, 0); + if (!r || irq == NO_IRQ) + return -ENXIO; + + r = request_mem_region(r->start, 0x100, "IMXMCI"); + if (!r) + return -EBUSY; + + mmc = mmc_alloc_host(sizeof(struct imxmci_host), dev); + if (!mmc) { + ret = -ENOMEM; + goto out; + } + + mmc->ops = &imxmci_ops; + mmc->f_min = 150000; + mmc->f_max = CLK_RATE; + mmc->ocr_avail = MMC_VDD_32_33; + + host = mmc_priv(mmc); + host->mmc = mmc; + host->dma = -1; + host->pdata = pdev->dev.platform_data; + + spin_lock_init(&host->lock); + host->res = r; + host->irq = irq; + + imx_gpio_mode(PB8_PF_SD_DAT0); + imx_gpio_mode(PB9_PF_SD_DAT1); + imx_gpio_mode(PB10_PF_SD_DAT2); + imx_gpio_mode(PB12_PF_SD_CLK); + imx_gpio_mode(PB13_PF_SD_CMD); + + imxmci_softreset(); + + if ( MMC_REV_NO != 0x390 ) { + printk("%s: wrong rev.no. 0x%08x. aborting.\n", + DRIVER_NAME,MMC_REV_NO); + goto out; + } + + MMC_READ_TO = 0x2db4; /* recommended in data sheet */ + + host->imask = INT_MASK_BUF_READY | INT_MASK_DATA_TRAN | + INT_MASK_WRITE_OP_DONE | INT_MASK_SDIO | + INT_MASK_AUTO_CARD_DETECT; + MMC_INT_MASK = host->imask; + + + host->dma = imx_request_dma(DRIVER_NAME, DMA_PRIO_LOW, imxmci_dma_irq, NULL, host); + if (host->dma < 0) { + ret = -EBUSY; + goto out; + } + + ret = request_irq(host->irq, imxmci_irq, 0, DRIVER_NAME, host); + if (ret) + goto out; + + host->present = host->pdata->card_present(); + init_timer(&host->timer); + host->timer.data = (unsigned long)host; + host->timer.function = imxmci_check_status; + add_timer(&host->timer); + mod_timer(&host->timer, jiffies + (HZ>>1)); + + dev_set_drvdata(dev, mmc); + + mmc_add_host(mmc); + + return 0; + +out: + if (host) { + if (host->dma >= 0) + imx_free_dma(host->dma); + } + if (mmc) + mmc_free_host(mmc); + release_resource(r); + return ret; +} + +static int imxmci_remove(struct device *dev) +{ + struct mmc_host *mmc = dev_get_drvdata(dev); + + dev_set_drvdata(dev, NULL); + + if (mmc) { + struct imxmci_host *host = mmc_priv(mmc); + + del_timer_sync(&host->timer); + mmc_remove_host(mmc); + + free_irq(host->irq, host); + imx_free_dma(host->dma); + + release_resource(host->res); + + mmc_free_host(mmc); + } + return 0; +} + +#ifdef CONFIG_PM +static int imxmci_suspend(struct device *dev, u32 state, u32 level) +{ + struct mmc_host *mmc = dev_get_drvdata(dev); + int ret = 0; + + if (mmc && level == SUSPEND_DISABLE) + ret = mmc_suspend_host(mmc, state); + + return ret; +} + +static int imxmci_resume(struct device *dev, u32 level) +{ + struct mmc_host *mmc = dev_get_drvdata(dev); + int ret = 0; + + if (mmc && level == RESUME_ENABLE) + ret = mmc_resume_host(mmc); + + return ret; +} +#else +#define imxmci_suspend NULL +#define imxmci_resume NULL +#endif /* CONFIG_PM */ + +static struct device_driver imxmci_driver = { + .name = "imx-mmc", + .bus = &platform_bus_type, + .probe = imxmci_probe, + .remove = imxmci_remove, + .suspend = imxmci_suspend, + .resume = imxmci_resume, +}; + +static int __init imxmci_init(void) +{ + return driver_register(&imxmci_driver); +} + +static void __exit imxmci_exit(void) +{ + driver_unregister(&imxmci_driver); +} + +module_init(imxmci_init); +module_exit(imxmci_exit); + +MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); +MODULE_AUTHOR("Sascha Hauer, Pengutronix"); +MODULE_LICENSE("GPL"); Index: drivers/mmc/Makefile =================================================================== --- a/drivers/mmc/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/mmc/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -17,6 +17,7 @@ # obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o +obj-$(CONFIG_MMC_IMX) += imxmmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o Index: drivers/net/Kconfig =================================================================== --- a/drivers/net/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/net/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -1353,7 +1353,7 @@ config CS89x0 tristate "CS89x0 support" - depends on NET_PCI && (ISA || ARCH_IXDP2X01) + depends on (ISA || ARCH_IXDP2X01 || ARCH_MX1ADS) ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the @@ -1365,6 +1365,18 @@ . The module will be called cs89x. +config DM9000 + tristate "DM9000 support" + depends on ARM && NET_ETHERNET + select CRC32 + select MII + ---help--- + Support for DM9000 chipset. + + To compile this driver as a module, choose M here and read + . The module will be + called dm9000. + config TC35815 tristate "TOSHIBA TC35815 Ethernet support" depends on NET_PCI && PCI && TOSHIBA_JMR3927 Index: drivers/net/dm9000x.c =================================================================== --- a/drivers/net/dm9000x.c (revision 0) +++ b/drivers/net/dm9000x.c (revision 490) @@ -0,0 +1,1320 @@ +/* + * dm9000.c: Version 1.2 03/18/2003 + * + * A Davicom DM9000 ISA NIC fast Ethernet driver for Linux. + * Copyright (C) 1997 Sten Wang + * + * 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. + * + * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. + * + * V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match + * 06/22/2001 Support DM9801 progrmming + * E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000 + * E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200 + * R17 = (R17 & 0xfff0) | NF + 3 + * E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200 + * R17 = (R17 & 0xfff0) | NF + * + * v1.00 modify by simon 2001.9.5 + * change for kernel 2.4.x + * + * v1.1 11/09/2001 fix force mode bug + * + * v1.2 03/18/2003 Weilun Huang : + * Fixed phy reset. + * Added tx/rx 32 bit mode. + * Cleaned up for kernel merge. + * + * 03/03/2004 Sascha Hauer + * Port to 2.6 kernel + * + * 24-Sep-2004 Ben Dooks + * Cleanup of code to remove ifdefs + * Allowed platform device data to influence access width + * Reformatting areas of code + + */ + +#if defined(MODVERSIONS) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* FIXME: where does this file come from? [RSC] */ + +#include +#include +#include + +#include "dm9000x.h" + +/* Board/System/Debug information/definition ---------------- */ + +#define DM9000_REG00 0x00 +#define DM9000_REG05 0x30 /* SKIP_CRC/SKIP_LONG */ +#define DM9000_REG08 0x27 +#define DM9000_REG09 0x38 +#define DM9000_REG0A 0xff +#define DM9000_REGFF 0x83 /* IMR */ + +#define DM9000_PHY 0x40 /* PHY address 0x01 */ + +#define TRUE 1 +#define FALSE 0 + +#define CARDNAME "dm9000" +#define PFX CARDNAME ": " + +#define DMFE_TIMER_WUT jiffies+(HZ*2) /* timer wakeup time : 2 second */ +#define DMFE_TX_TIMEOUT (HZ*2) /* tx packet time-out time 1.5 s" */ + +#define DMFE_DEBUG 0 + +#if DMFE_DEBUG > 2 +#define PRINTK3(args...) printk(CARDNAME ": " args) +#else +#define PRINTK3(args...) do { } while(0) +#endif + +#if DMFE_DEBUG > 1 +#define PRINTK2(args...) printk(CARDNAME ": " args) +#else +#define PRINTK2(args...) do { } while(0) +#endif + +#if DMFE_DEBUG > 0 +#define PRINTK1(args...) printk(CARDNAME ": " args) +#define PRINTK(args...) printk(CARDNAME ": " args) +#else +#define PRINTK1(args...) do { } while(0) +#define PRINTK(args...) printk(KERN_DEBUG args) +#endif + +enum DM9000_PHY_mode { + DM9000_10MHD = 0, + DM9000_100MHD = 1, + DM9000_10MFD = 4, + DM9000_100MFD = 5, + DM9000_AUTO = 8, + DM9000_1M_HPNA = 0x10 +}; + +/* Structure/enum declaration ------------------------------- */ +typedef struct board_info { + + u32 runt_length_counter; /* counter: RX length < 64byte */ + u32 long_length_counter; /* counter: RX length > 1514byte */ + u32 reset_counter; /* counter: RESET */ + u32 reset_tx_timeout; /* RESET caused by TX Timeout */ + u32 reset_rx_status; /* RESET caused by RX Statsus wrong */ + + void __iomem *io_addr; /* Register I/O base address */ + void __iomem *io_data; /* Data I/O address */ + u16 irq; /* IRQ */ + + u16 tx_pkt_cnt; + u16 queue_pkt_len; + u16 queue_start_addr; + u16 dbug_cnt; + u8 reg0, reg5, reg8, reg9, rega; /* registers saved */ + u8 op_mode; /* PHY operation mode */ + u8 io_mode; /* 0:word, 2:byte */ + u8 phy_addr; + u8 device_wait_reset; /* device state */ + + void (*inblk)(void __iomem *port, void *data, int length); + void (*outblk)(void __iomem *port, void *data, int length); + void (*dumpblk)(void __iomem *port, int length); + + struct resource *addr_res; /* resources found */ + struct resource *data_res; + struct resource *addr_req; /* resources requested */ + struct resource *data_req; + struct resource *irq_res; + + struct timer_list timer; + struct net_device_stats stats; + unsigned char srom[128]; + spinlock_t lock; + + struct mii_if_info mii; + u32 msg_enable; + +} board_info_t; + +/* Global variable declaration ----------------------------- */ +static int dmfe_debug = 0; + +/* For module input parameter */ +static int debug = 0; +static int mode = DM9000_AUTO; +static int media_mode = DM9000_AUTO; +static u8 reg5 = DM9000_REG05; +static u8 reg8 = DM9000_REG08; +static u8 reg9 = DM9000_REG09; +static u8 rega = DM9000_REG0A; +static u8 nfloor = 0; + +/* function declaration ------------------------------------- */ +static int dmfe_probe(struct device *); +static int dmfe_open(struct net_device *); +static int dmfe_start_xmit(struct sk_buff *, struct net_device *); +static int dmfe_stop(struct net_device *); +static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int); + + +static void dmfe_timer(unsigned long); +static void dmfe_init_dm9000(struct net_device *); + +static struct net_device_stats *dmfe_get_stats(struct net_device *); + +static irqreturn_t dmfe_interrupt(int, void *, struct pt_regs *); + +static int dmfe_phy_read(struct net_device *dev, int phyaddr_unsused, int reg); +static void dmfe_phy_write(struct net_device *dev, int phyaddr_unused, int reg, + int value); +static u16 read_srom_word(board_info_t *, int); +static void dmfe_rx(struct net_device *); +static void dm9000_hash_table(struct net_device *); + +//#define DM9000_PROGRAM_EEPROM +#ifdef DM9000_PROGRAM_EEPROM +static void program_eeprom(board_info_t * db); +#endif +/* DM9000 network board routine ---------------------------- */ + +static void +dmfe_reset(board_info_t * db) +{ + PRINTK1("dm9000x: resetting\n"); + /* RESET device */ + writeb(DMFE_NCR, db->io_addr); + udelay(200); /* delay 100us */ + writeb(NCR_RST, db->io_data); + udelay(200); /* delay 100us */ +} + +/* + * Read a byte from I/O port + */ +static u8 +ior(board_info_t * db, int reg) +{ + writeb(reg, db->io_addr); + return readb(db->io_data); +} + +/* + * Write a byte to I/O port + */ + +static void +iow(board_info_t * db, int reg, int value) +{ + writeb(reg, db->io_addr); + writeb(value, db->io_data); +} + +/* routines for sending block to chip */ + +static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count) +{ + writesb(reg, data, count); +} + +static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count) +{ + writesw(reg, data, (count+1) >> 1); +} + +static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count) +{ + writesl(reg, data, (count+3) >> 2); +} + +/* input block from chip to memory */ + +static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count) +{ + readsb(reg, data, count+1); +} + + +static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count) +{ + readsw(reg, data, (count+1) >> 1); +} + +static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count) +{ + readsl(reg, data, (count+3) >> 2); +} + +/* dump block from chip to null */ + +static void dm9000_dumpblk_8bit(void __iomem *reg, int count) +{ + int i; + int tmp; + + for (i = 0; i < count; i++) + tmp = readb(reg); +} + +static void dm9000_dumpblk_16bit(void __iomem *reg, int count) +{ + int i; + int tmp; + + count = (count + 1) >> 1; + + for (i = 0; i < count; i++) + tmp = readw(reg); +} + +static void dm9000_dumpblk_32bit(void __iomem *reg, int count) +{ + int i; + int tmp; + + count = (count + 3) >> 2; + + for (i = 0; i < count; i++) + tmp = readl(reg); +} + +/* dmfe_set_io + * + * select the specified set of io routines to use with the + * device +*/ + +static void dmfe_set_io(struct board_info *db, int byte_width) +{ + /* use the size of the data resource to work out what IO + * routines we want to use + */ + + switch (byte_width) { + case 1: + db->dumpblk = dm9000_dumpblk_8bit; + db->outblk = dm9000_outblk_8bit; + db->inblk = dm9000_inblk_8bit; + break; + + case 2: + db->dumpblk = dm9000_dumpblk_16bit; + db->outblk = dm9000_outblk_16bit; + db->inblk = dm9000_inblk_16bit; + break; + + case 3: + printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n"); + db->dumpblk = dm9000_dumpblk_16bit; + db->outblk = dm9000_outblk_16bit; + db->inblk = dm9000_inblk_16bit; + break; + + case 4: + default: + db->dumpblk = dm9000_dumpblk_32bit; + db->outblk = dm9000_outblk_32bit; + db->inblk = dm9000_inblk_32bit; + break; + } +} + + +/* dmfe_release_board + * + * release a board, and any mapped resources +*/ + +static void +dmfe_release_board(struct platform_device *pdev, struct board_info *db) +{ + if (db->data_res == NULL) { + if (db->addr_res != NULL) + release_mem_region((unsigned long)db->io_addr, 4); + return; + } + + /* unmap our resources */ + + iounmap(db->io_addr); + iounmap(db->io_data); + + /* release the resources */ + + if (db->data_req != NULL) { + release_resource(db->data_req); + kfree(db->data_req); + } + + if (db->addr_res != NULL) { + release_resource(db->data_req); + kfree(db->addr_req); + } +} + +#define res_size(_r) (((_r)->end - (_r)->start) + 1) + +/* + Search DM9000 board, allocate space and register it +*/ +static int +dmfe_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct dm9000_plat_data *pdata = pdev->dev.platform_data; + struct board_info *db; /* Point a board information structure */ + struct net_device *ndev; + unsigned long base; + int ret = 0; + int iosize; + int i; + u32 id_val; + + printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); + + /* Init network device */ + ndev = alloc_etherdev(sizeof (struct board_info)); + if (!ndev) { + printk("%s: could not allocate device.\n", CARDNAME); + return -ENOMEM; + } + + SET_MODULE_OWNER(ndev); + SET_NETDEV_DEV(ndev, dev); + + PRINTK2("dmfe_probe()"); + + /* setup board info structure */ + db = (struct board_info *) ndev->priv; + memset(db, 0, sizeof (*db)); + + if (pdev->num_resources < 2) { + ret = -ENODEV; + goto out; + } + + switch (pdev->num_resources) { + case 2: + base = pdev->resource[0].start; + + if (!request_mem_region(base, 4, ndev->name)) { + ret = -EBUSY; + goto out; + } + + ndev->base_addr = base; + ndev->irq = pdev->resource[1].start; + db->io_addr = (void *)base; + db->io_data = (void *)(base + 4); + + break; + + case 3: + db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + + if (db->addr_res == NULL || db->data_res == NULL) { + printk(KERN_ERR PFX "insufficient resources\n"); + ret = -ENOENT; + goto out; + } + + i = res_size(db->addr_res); + db->addr_req = request_mem_region(db->addr_res->start, i, + pdev->name); + + if (db->addr_req == NULL) { + printk(KERN_ERR PFX "cannot claim address reg area\n"); + ret = -EIO; + goto out; + } + + db->io_addr = ioremap(db->addr_res->start, i); + + if (db->io_addr == NULL) { + printk(KERN_ERR "failed to ioremap address reg\n"); + ret = -EINVAL; + goto out; + } + + iosize = res_size(db->data_res); + db->data_req = request_mem_region(db->data_res->start, iosize, + pdev->name); + + if (db->data_req == NULL) { + printk(KERN_ERR PFX "cannot claim data reg area\n"); + ret = -EIO; + goto out; + } + + db->io_data = ioremap(db->data_res->start, iosize); + + if (db->io_data == NULL) { + printk(KERN_ERR "failed to ioremap data reg\n"); + ret = -EINVAL; + goto out; + } + + /* fill in parameters for net-dev structure */ + + ndev->base_addr = (unsigned long)db->io_addr; + ndev->irq = db->irq_res->start; + + /* ensure at least we have a default set of IO routines */ + dmfe_set_io(db, iosize); + + /* check to see if anything is being over-ridden */ + if (pdata != NULL) { + /* check to see if the driver wants to over-ride the + * default IO width */ + + if (pdata->flags & DM9000_PLATF_8BITONLY) + dmfe_set_io(db, 1); + + if (pdata->flags & DM9000_PLATF_16BITONLY) + dmfe_set_io(db, 2); + + if (pdata->flags & DM9000_PLATF_32BITONLY) + dmfe_set_io(db, 4); + + /* check to see if there are any IO routine + * over-rides */ + + if (pdata->inblk != NULL) + db->inblk = pdata->inblk; + + if (pdata->outblk != NULL) + db->outblk = pdata->outblk; + + if (pdata->dumpblk != NULL) + db->dumpblk = pdata->dumpblk; + } + } + + + dmfe_reset(db); + + /* try two times, DM9000 sometimes gets the first read wrong */ + for (i = 0; i < 2; i++) { + id_val = ior(db, DMFE_VIDL); + id_val |= (u32)ior(db, DMFE_VIDH) << 8; + id_val |= (u32)ior(db, DMFE_PIDL) << 16; + id_val |= (u32)ior(db, DMFE_PIDH) << 24; + + if (id_val == DM9000_ID) + break; + printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val); + } + + if (id_val != DM9000_ID) { + printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val); + goto release; + } + + /* from this point we assume that we have found a DM9000 */ + + /* driver system function */ + ether_setup(ndev); + + ndev->open = &dmfe_open; + ndev->hard_start_xmit = &dmfe_start_xmit; + ndev->stop = &dmfe_stop; + ndev->get_stats = &dmfe_get_stats; + ndev->set_multicast_list = &dm9000_hash_table; + ndev->do_ioctl = &dmfe_do_ioctl; + +#ifdef DM9000_PROGRAM_EEPROM + program_eeprom(db); +#endif + db->msg_enable = NETIF_MSG_LINK; + db->mii.phy_id_mask = 0x1f; + db->mii.reg_num_mask = 0x1f; + db->mii.force_media = 0; + db->mii.full_duplex = 0; + db->mii.dev = ndev; + db->mii.mdio_read = dmfe_phy_read; + db->mii.mdio_write = dmfe_phy_write; + + /* Read SROM content */ + for (i = 0; i < 64; i++) + ((u16 *) db->srom)[i] = read_srom_word(db, i); + + /* Set Node Address */ + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = db->srom[i]; + + if (!is_valid_ether_addr(ndev->dev_addr)) + printk("%s: Invalid ethernet MAC address. Please " + "set using ifconfig\n", ndev->name); + + dev_set_drvdata(dev, ndev); + ret = register_netdev(ndev); + + if (ret == 0) { + printk("%s: dm9000 at %p,%p IRQ %d MAC: ", + ndev->name, db->io_addr, db->io_data, ndev->irq); + for (i = 0; i < 5; i++) + printk("%02x:", ndev->dev_addr[i]); + printk("%02x\n", ndev->dev_addr[5]); + } + return 0; + + release: + out: + printk("%s: not found (%d).\n", CARDNAME, ret); + + dmfe_release_board(pdev, db); + kfree(ndev); + + return ret; +} + +/* + * Open the interface. + * The interface is opened whenever "ifconfig" actives it. + */ +static int +dmfe_open(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + + PRINTK2("entering dmfe_open\n"); + + if (request_irq(dev->irq, &dmfe_interrupt, SA_SHIRQ, dev->name, dev)) + return -EAGAIN; + + /* Initialize DM9000 board */ + dmfe_reset(db); + dmfe_init_dm9000(dev); + + /* Init driver variable */ + db->dbug_cnt = 0; + db->runt_length_counter = 0; + db->long_length_counter = 0; + db->reset_counter = 0; + db->device_wait_reset = 0; + + /* set and active a timer process */ + init_timer(&db->timer); + db->timer.expires = DMFE_TIMER_WUT * 2; + db->timer.data = (unsigned long) dev; + db->timer.function = &dmfe_timer; + add_timer(&db->timer); + + mii_check_media(&db->mii, netif_msg_link(db), 1); + netif_start_queue(dev); + + return 0; +} + +/* + * Set PHY operating mode + */ +static void +set_PHY_mode(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000; + + if (!(db->op_mode & DM9000_AUTO)) { + + switch (db->op_mode) { + case DM9000_10MHD: + phy_reg4 = ADVERTISE_10HALF | ADVERTISE_CSMA; + phy_reg0 = 0; + break; + case DM9000_10MFD: + phy_reg4 = ADVERTISE_10FULL | ADVERTISE_CSMA; + phy_reg0 = BMCR_ANENABLE | BMCR_FULLDPLX; + break; + case DM9000_100MHD: + phy_reg4 = ADVERTISE_100HALF | ADVERTISE_CSMA; + phy_reg0 = BMCR_SPEED100; + break; + case DM9000_100MFD: + phy_reg4 = ADVERTISE_100FULL | ADVERTISE_CSMA; + phy_reg0 = + BMCR_SPEED100 | BMCR_ANENABLE | BMCR_FULLDPLX; + break; + } + dmfe_phy_write(dev, 0, MII_ADVERTISE, phy_reg4); /* Set PHY media mode */ + dmfe_phy_write(dev, 0, MII_BMCR, phy_reg0); /* Tmp */ + } + + iow(db, DMFE_GPCR, 0x01); /* Let GPIO0 output */ + iow(db, DMFE_GPR, 0x00); /* Enable PHY */ +} + +/* + * Initilize dm9000 board + */ +static void +dmfe_init_dm9000(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + + PRINTK1("entering %s\n",__FUNCTION__); + + /* I/O mode */ + db->io_mode = ior(db, DMFE_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ + + /* GPIO0 on pre-activate PHY */ + iow(db, DMFE_GPR, 0x00); /*REG_1F bit0 activate phyxcer */ + + /* Set PHY */ + db->op_mode = media_mode; + set_PHY_mode(dev); + + /* Init needed register value */ + db->reg0 = DM9000_REG00; + + /* User passed argument */ + db->reg5 = reg5; + db->reg8 = reg8; + db->reg9 = reg9; + db->rega = rega; + + /* Program operating register */ + iow(db, DMFE_NCR, db->reg0); + iow(db, DMFE_TCR, 0); /* TX Polling clear */ + iow(db, DMFE_BPTR, 0x3f); /* Less 3Kb, 200us */ + iow(db, DMFE_FCTR, db->reg9); /* Flow Control : High/Low Water */ + iow(db, DMFE_FCR, db->rega); /* Flow Control */ + iow(db, DMFE_SMCR, 0); /* Special Mode */ + iow(db, DMFE_NSR, 0x2c); /* clear TX status */ + iow(db, DMFE_ISR, ISR_CLR_STATUS); /* Clear interrupt status */ + + /* Set address filter table */ + dm9000_hash_table(dev); + + /* Activate DM9000 */ + iow(db, DMFE_RCR, db->reg5 | 1); /* RX enable */ + iow(db, DMFE_IMR, DM9000_REGFF); /* Enable TX/RX interrupt mask */ + + /* Init Driver variable */ + db->tx_pkt_cnt = 0; + db->queue_pkt_len = 0; + dev->trans_start = 0; + spin_lock_init(&db->lock); +} + +/* + * Hardware start transmission. + * Send a packet to media from the upper layer. + */ +static int +dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + + PRINTK3("dmfe_start_xmit\n"); + + if (db->tx_pkt_cnt > 1) + return 1; + + netif_stop_queue(dev); + + /* Disable all interrupts */ + iow(db, DMFE_IMR, IMR_PAR); + + /* Move data to DM9000 TX RAM */ + writeb(DMFE_MWCMD, db->io_addr); + + (db->outblk)(db->io_data, skb->data, skb->len); + + /* TX control: First packet immediately send, second packet queue */ + if (db->tx_pkt_cnt == 0) { + + /* First Packet */ + db->tx_pkt_cnt++; + + /* Set TX length to DM9000 */ + iow(db, DMFE_TXPLL, skb->len & 0xff); + iow(db, DMFE_TXPLH, (skb->len >> 8) & 0xff); + + /* Issue TX polling command */ + iow(db, DMFE_TCR, TCR_TXREQ); /* Cleared after TX complete */ + + dev->trans_start = jiffies; /* saved the time stamp */ + + } else { + /* Second packet */ + db->tx_pkt_cnt++; + db->queue_pkt_len = skb->len; + } + + /* free this SKB */ + dev_kfree_skb(skb); + + /* Re-enable resource check */ + if (db->tx_pkt_cnt == 1) + netif_wake_queue(dev); + + /* Re-enable interrupt */ + iow(db, DMFE_IMR, IMR_PAR | IMR_PTM | IMR_PRM); + + return 0; +} + +static void +dmfe_shutdown(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + + /* RESET devie */ + dmfe_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ + iow(db, DMFE_GPR, 0x01); /* Power-Down PHY */ + iow(db, DMFE_IMR, IMR_PAR); /* Disable all interrupt */ + iow(db, DMFE_RCR, 0x00); /* Disable RX */ +} + +/* + Stop the interface. + The interface is stopped when it is brought. +*/ +static int +dmfe_stop(struct net_device *ndev) +{ + board_info_t *db = (board_info_t *) ndev->priv; + + PRINTK1("entering %s\n",__FUNCTION__); + + /* deleted timer */ + del_timer(&db->timer); + + netif_stop_queue(ndev); + netif_carrier_off(ndev); + + /* free interrupt */ + free_irq(ndev->irq, ndev); + + dmfe_shutdown(ndev); + + return 0; +} + +/* + DM9000 interrupt handler + receive the packet to upper layer, free the transmitted packet +*/ + +void +dmfe_tx_done(struct net_device *dev, board_info_t * db) +{ + int tx_status = ior(db, DMFE_NSR); /* Got TX status */ + + if (tx_status & 0xc) { + /* One packet sent complete */ + db->tx_pkt_cnt--; + dev->trans_start = 0; + db->stats.tx_packets++; + + /* Queue packet check & send */ + if (db->tx_pkt_cnt > 0) { + iow(db, DMFE_TXPLL, db->queue_pkt_len & 0xff); + iow(db, DMFE_TXPLH, (db->queue_pkt_len >> 8) & 0xff); + iow(db, DMFE_TCR, TCR_TXREQ); + dev->trans_start = jiffies; + } + netif_wake_queue(dev); + } +} + +static irqreturn_t +dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + board_info_t *db; + int int_status; + u8 reg_save; + + PRINTK3("entering %s\n",__FUNCTION__); + + if (!dev) { + PRINTK1("dmfe_interrupt() without DEVICE arg\n"); + return IRQ_HANDLED; + } + + /* A real interrupt coming */ + db = (board_info_t *) dev->priv; + spin_lock(&db->lock); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Disable all interrupts */ + iow(db, DMFE_IMR, IMR_PAR); + + /* Got DM9000 interrupt status */ + int_status = ior(db, DMFE_ISR); /* Got ISR */ + iow(db, DMFE_ISR, int_status); /* Clear ISR status */ + + /* Received the coming packet */ + if (int_status & ISR_PRS) + dmfe_rx(dev); + + /* Trnasmit Interrupt check */ + if (int_status & ISR_PTS) + dmfe_tx_done(dev, db); + + /* Re-enable interrupt mask */ + iow(db, DMFE_IMR, IMR_PAR | IMR_PTM | IMR_PRM); + + /* Restore previous register address */ + writeb(reg_save, db->io_addr); + + spin_unlock(&db->lock); + + return IRQ_HANDLED; +} + +/* + * Get statistics from driver. + */ +static struct net_device_stats * +dmfe_get_stats(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + return &db->stats; +} + +/* + * Process the upper socket ioctl command + */ +static int +dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + PRINTK1("entering %s\n",__FUNCTION__); + return 0; +} + +/* + * A periodic timer routine + * Dynamic media sense, allocated Rx buffer... + */ +static void +dmfe_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + board_info_t *db = (board_info_t *) dev->priv; + u8 reg_save; + + PRINTK3("dmfe_timer()\n"); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* TX timeout check */ + if (dev->trans_start + && ((jiffies - dev->trans_start) > DMFE_TX_TIMEOUT)) { + printk("tx timeout\n"); + db->device_wait_reset = 1; + db->reset_tx_timeout++; + } + + /* DM9000 dynamic RESET check and do */ + if (db->device_wait_reset) { + netif_stop_queue(dev); + db->reset_counter++; + db->device_wait_reset = 0; + dev->trans_start = 0; + dmfe_reset(db); + dmfe_init_dm9000(dev); + netif_wake_queue(dev); + } + + mii_check_media(&db->mii, netif_msg_link(db), 0); + + /* Restore previous register address */ + writeb(reg_save, db->io_addr); + + /* Set timer again */ + db->timer.expires = DMFE_TIMER_WUT; + add_timer(&db->timer); +} + +#if 0 +/* dump a packet to screen */ +static void +dump_packet(unsigned char *buf, int len) +{ + int i = 0; + printk("\n------------------------\n"); + while (i < len) { + printk("%02x ", buf[i]); + i++; + if (!(i % 8)) + printk("\n"); + } + + printk("----------------------\n"); +} +#endif + +struct dm9000_rxhdr { + u16 RxStatus; + u16 RxLen; +} __attribute__((__packed__)); + +/* + * Received a packet and pass to upper layer + */ +static void +dmfe_rx(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + struct dm9000_rxhdr rxhdr; + struct sk_buff *skb; + u8 rxbyte, *rdptr; + int GoodPacket; + int RxLen; + + /* Check packet ready or not */ + do { + ior(db, DMFE_MRCMDX); /* Dummy read */ + + /* Get most updated data */ + rxbyte = readb(db->io_data); + + /* Status check: this byte must be 0 or 1 */ + if (rxbyte > DM9000_PKT_RDY) { + printk("status check failed: %d\n", rxbyte); + iow(db, DMFE_RCR, 0x00); /* Stop Device */ + iow(db, DMFE_ISR, IMR_PAR); /* Stop INT request */ + db->device_wait_reset = TRUE; + db->reset_rx_status++; + return; + } + + if (rxbyte != DM9000_PKT_RDY) + return; + + /* A packet ready now & Get status/length */ + GoodPacket = TRUE; + writeb(DMFE_MRCMD, db->io_addr); + + (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr)); + + RxLen = rxhdr.RxLen; + + /* Packet Status check */ + if (RxLen < 0x40) { + GoodPacket = FALSE; + db->runt_length_counter++; + PRINTK1("Bad Packet received (runt)\n"); + } + + if (RxLen > DM9000_PKT_MAX) { + PRINTK1("RST: RX Len:%x\n", RxLen); + db->device_wait_reset = TRUE; + db->long_length_counter++; + } + + if (rxhdr.RxStatus & 0xbf00) { + GoodPacket = FALSE; + if (rxhdr.RxStatus & 0x100) { + PRINTK1("fifo error\n"); + db->stats.rx_fifo_errors++; + } + if (rxhdr.RxStatus & 0x200) { + PRINTK1("crc error\n"); + db->stats.rx_crc_errors++; + } + if (rxhdr.RxStatus & 0x8000) { + PRINTK1("length error\n"); + db->stats.rx_length_errors++; + } + } + + /* Move data from DM9000 */ + if (GoodPacket + && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) { + skb->dev = dev; + skb_reserve(skb, 2); + rdptr = (u8 *) skb_put(skb, RxLen - 4); + + /* Read received packet from RX SRAM */ + + (db->inblk)(db->io_data, rdptr, RxLen); + + /* Pass to upper layer */ + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + db->stats.rx_packets++; + + } else { + /* need to dump the packet's data */ + + (db->dumpblk)(db->io_data, RxLen); + } + } while (rxbyte == DM9000_PKT_RDY); +} + +/* + * Read a word data from SROM + */ +static u16 +read_srom_word(board_info_t * db, int offset) +{ + iow(db, DMFE_EPAR, offset); + iow(db, DMFE_EPCR, EPCR_ERPRR); + udelay(8000); /* according to the datasheet 200us should be enough, + but it doesn't work */ + iow(db, DMFE_EPCR, 0x0); + return (ior(db, DMFE_EPDRL) + (ior(db, DMFE_EPDRH) << 8)); +} + +#ifdef DM9000_PROGRAM_EEPROM +/* + * Write a word data to SROM + */ +static void +write_srom_word(board_info_t * db, int offset, u16 val) +{ + iow(db, DMFE_EPAR, offset); + iow(db, DMFE_EPDRH, ((val >> 8) & 0xff)); + iow(db, DMFE_EPDRL, (val & 0xff)); + iow(db, DMFE_EPCR, EPCR_WEP | EPCR_ERPRW); + udelay(8000); /* same shit */ + iow(db, DMFE_EPCR, 0); +} + +/* + * Only for development: + * Here we write static data to the eeprom in case + * we don't have valid content on a new board + */ +static void +program_eeprom(board_info_t * db) +{ + u16 eeprom[] = { 0x0c00, 0x007f, 0x1300, /* MAC Address */ + 0x0000, /* Autoload: accept nothing */ + 0x0a46, 0x9000, /* Vendor / Product ID */ + 0x0000, /* pin control */ + 0x0000, + }; /* Wake-up mode control */ + int i; + for (i = 0; i < 8; i++) + write_srom_word(db, i, eeprom[i]); +} +#endif + + +/* + * Calculate the CRC valude of the Rx packet + * flag = 1 : return the reverse CRC (for the received packet CRC) + * 0 : return the normal CRC (for Hash Table index) + */ + +static unsigned long +cal_CRC(unsigned char *Data, unsigned int Len, u8 flag) +{ + + u32 crc = ether_crc_le(Len, Data); + + if (flag) + return ~crc; + + return crc; +} + +/* + * Set DM9000 multicast address + */ +static void +dm9000_hash_table(struct net_device *dev) +{ + board_info_t *db = (board_info_t *) dev->priv; + struct dev_mc_list *mcptr = dev->mc_list; + int mc_cnt = dev->mc_count; + u32 hash_val; + u16 i, oft, hash_table[4]; + + PRINTK2("dm9000_hash_table()\n"); + + for (i = 0, oft = 0x10; i < 6; i++, oft++) + iow(db, oft, dev->dev_addr[i]); + + /* Clear Hash Table */ + for (i = 0; i < 4; i++) + hash_table[i] = 0x0; + + /* broadcast address */ + hash_table[3] = 0x8000; + + /* the multicast address in Hash Table : 64 bits */ + for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { + hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; + hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); + } + + /* Write the hash table to MAC MD table */ + for (i = 0, oft = 0x16; i < 4; i++) { + iow(db, oft++, hash_table[i] & 0xff); + iow(db, oft++, (hash_table[i] >> 8) & 0xff); + } +} + + +/* + * Read a word from phyxcer + */ +static int +dmfe_phy_read(struct net_device *dev, int phy_reg_unused, int reg) +{ + board_info_t *db = (board_info_t *) dev->priv; + + /* Fill the phyxcer register into REG_0C */ + iow(db, DMFE_EPAR, DM9000_PHY | reg); + + iow(db, DMFE_EPCR, 0xc); /* Issue phyxcer read command */ + udelay(100); /* Wait read complete */ + iow(db, DMFE_EPCR, 0x0); /* Clear phyxcer read command */ + + /* The read data keeps on REG_0D & REG_0E */ + return (ior(db, DMFE_EPDRH) << 8) | ior(db, DMFE_EPDRL); +} + +/* + * Write a word to phyxcer + */ +static void +dmfe_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) +{ + board_info_t *db = (board_info_t *) dev->priv; + /* Fill the phyxcer register into REG_0C */ + iow(db, DMFE_EPAR, DM9000_PHY | reg); + + /* Fill the written data into REG_0D & REG_0E */ + iow(db, DMFE_EPDRL, (value & 0xff)); + iow(db, DMFE_EPDRH, ((value >> 8) & 0xff)); + + iow(db, DMFE_EPCR, 0xa); /* Issue phyxcer write command */ + udelay(500); /* Wait write complete */ + iow(db, DMFE_EPCR, 0x0); /* Clear phyxcer write command */ +} + +MODULE_PARM(debug, "i"); +MODULE_PARM(mode, "i"); +MODULE_PARM(reg5, "i"); +MODULE_PARM(reg9, "i"); +MODULE_PARM(rega, "i"); +MODULE_PARM(nfloor, "i"); + +static int +dmfe_drv_suspend(struct device *dev, u32 state, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); + + if (ndev && level == SUSPEND_DISABLE) { + if (netif_running(ndev)) { + netif_device_detach(ndev); + dmfe_shutdown(ndev); + } + } + return 0; +} + +static int +dmfe_drv_resume(struct device *dev, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); + board_info_t *db = (board_info_t *) ndev->priv; + + if (ndev && level == RESUME_ENABLE) { + + if (netif_running(ndev)) { + dmfe_reset(db); + dmfe_init_dm9000(ndev); + + netif_device_attach(ndev); + } + } + return 0; +} + +static int +dmfe_drv_remove(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev = dev_get_drvdata(dev); + + dev_set_drvdata(dev, NULL); + + unregister_netdev(ndev); + dmfe_release_board(pdev, (board_info_t *) ndev->priv); + kfree(ndev); /* free device structure */ + + PRINTK1("clean_module() exit\n"); + + return 0; +} + +static struct device_driver dmfe_driver = { + .name = "dm9000", + .bus = &platform_bus_type, + .probe = dmfe_probe, + .remove = dmfe_drv_remove, + .suspend = dmfe_drv_suspend, + .resume = dmfe_drv_resume, +}; + +static int __init +dmfe_init(void) +{ + if (debug) + dmfe_debug = debug; /* set debug flag */ + + switch (mode) { + case DM9000_10MHD: + case DM9000_100MHD: + case DM9000_10MFD: + case DM9000_100MFD: + case DM9000_1M_HPNA: + media_mode = mode; + break; + default: + media_mode = DM9000_AUTO; + } + + nfloor = (nfloor > 15) ? 0 : nfloor; + + return driver_register(&dmfe_driver); /* search board and register */ +} + +static void __exit +dmfe_cleanup(void) +{ + driver_unregister(&dmfe_driver); +} + +module_init(dmfe_init); +module_exit(dmfe_cleanup); + +MODULE_AUTHOR("Sascha Hauer, Ben Dooks"); +MODULE_DESCRIPTION("Davicom DM9000 network driver"); +MODULE_LICENSE("GPL"); Index: drivers/net/dm9000x.h =================================================================== --- a/drivers/net/dm9000x.h (revision 0) +++ b/drivers/net/dm9000x.h (revision 490) @@ -0,0 +1,133 @@ +/* + * dm9000 Ethernet + */ + +#ifndef _DM9000X_H_ +#define _DM9000X_H_ + +#define DM9000_ID 0x90000A46 + +/* although the registers are 16 bit, they are 32-bit aligned. + */ + +#define DMFE_NCR 0x00 +#define DMFE_NSR 0x01 +#define DMFE_TCR 0x02 +#define DMFE_TSR1 0x03 +#define DMFE_TSR2 0x04 +#define DMFE_RCR 0x05 +#define DMFE_RSR 0x06 +#define DMFE_ROCR 0x07 +#define DMFE_BPTR 0x08 +#define DMFE_FCTR 0x09 +#define DMFE_FCR 0x0A +#define DMFE_EPCR 0x0B +#define DMFE_EPAR 0x0C +#define DMFE_EPDRL 0x0D +#define DMFE_EPDRH 0x0E +#define DMFE_WCR 0x0F + +#define DMFE_PAR 0x10 +#define DMFE_MAR 0x16 + +#define DMFE_GPCR 0x1e +#define DMFE_GPR 0x1f +#define DMFE_TRPAL 0x22 +#define DMFE_TRPAH 0x23 +#define DMFE_RWPAL 0x24 +#define DMFE_RWPAH 0x25 + +#define DMFE_VIDL 0x28 +#define DMFE_VIDH 0x29 +#define DMFE_PIDL 0x2A +#define DMFE_PIDH 0x2B + +#define DMFE_CHIPR 0x2C +#define DMFE_SMCR 0x2F + +#define DMFE_MRCMDX 0xF0 +#define DMFE_MRCMD 0xF2 +#define DMFE_MRRL 0xF4 +#define DMFE_MRRH 0xF5 +#define DMFE_MWCMDX 0xF6 +#define DMFE_MWCMD 0xF8 +#define DMFE_MWRL 0xFA +#define DMFE_MWRH 0xFB +#define DMFE_TXPLL 0xFC +#define DMFE_TXPLH 0xFD +#define DMFE_ISR 0xFE +#define DMFE_IMR 0xFF + +#define NCR_EXT_PHY (1<<7) +#define NCR_WAKEEN (1<<6) +#define NCR_FCOL (1<<4) +#define NCR_FDX (1<<3) +#define NCR_LBK (3<<1) +#define NCR_RST (1<<0) + +#define NSR_SPEED (1<<7) +#define NSR_LINKST (1<<6) +#define NSR_WAKEST (1<<5) +#define NSR_TX2END (1<<3) +#define NSR_TX1END (1<<2) +#define NSR_RXOV (1<<1) + +#define TCR_TJDIS (1<<6) +#define TCR_EXCECM (1<<5) +#define TCR_PAD_DIS2 (1<<4) +#define TCR_CRC_DIS2 (1<<3) +#define TCR_PAD_DIS1 (1<<2) +#define TCR_CRC_DIS1 (1<<1) +#define TCR_TXREQ (1<<0) + +#define TSR_TJTO (1<<7) +#define TSR_LC (1<<6) +#define TSR_NC (1<<5) +#define TSR_LCOL (1<<4) +#define TSR_COL (1<<3) +#define TSR_EC (1<<2) + +#define RCR_WTDIS (1<<6) +#define RCR_DIS_LONG (1<<5) +#define RCR_DIS_CRC (1<<4) +#define RCR_ALL (1<<3) +#define RCR_RUNT (1<<2) +#define RCR_PRMSC (1<<1) +#define RCR_RXEN (1<<0) + +#define RSR_RF (1<<7) +#define RSR_MF (1<<6) +#define RSR_LCS (1<<5) +#define RSR_RWTO (1<<4) +#define RSR_PLE (1<<3) +#define RSR_AE (1<<2) +#define RSR_CE (1<<1) +#define RSR_FOE (1<<0) + +#define FCTR_HWOT(ot) (( ot & 0xf ) << 4 ) +#define FCTR_LWOT(ot) ( ot & 0xf ) + +#define IMR_PAR (1<<7) +#define IMR_ROOM (1<<3) +#define IMR_ROM (1<<2) +#define IMR_PTM (1<<1) +#define IMR_PRM (1<<0) + +#define ISR_ROOS (1<<3) +#define ISR_ROS (1<<2) +#define ISR_PTS (1<<1) +#define ISR_PRS (1<<0) +#define ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS) + +#define EPCR_REEP (1<<5) +#define EPCR_WEP (1<<4) +#define EPCR_EPOS (1<<3) +#define EPCR_ERPRR (1<<2) +#define EPCR_ERPRW (1<<1) +#define EPCR_ERRE (1<<0) + +#define DM9000_PKT_RDY 0x01 /* Packet ready to receive */ +#define DM9000_PKT_MAX 1536 /* Received packet max size */ + +#endif /* _DM9000X_H_ */ + Index: drivers/net/Makefile =================================================================== --- a/drivers/net/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/net/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -171,6 +171,7 @@ obj-$(CONFIG_HYDRA) += hydra.o 8390.o obj-$(CONFIG_ARIADNE) += ariadne.o obj-$(CONFIG_CS89x0) += cs89x0.o +obj-$(CONFIG_DM9000) += dm9000x.o obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MACMACE) += macmace.o obj-$(CONFIG_MAC89x0) += mac89x0.o Index: drivers/net/cs89x0.c =================================================================== --- a/drivers/net/cs89x0.c (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/net/cs89x0.c (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -143,6 +143,11 @@ #include #endif +#ifdef CONFIG_ARCH_MX1ADS +#include +#include +#endif /* CONFIG_MACH_MX1ADS */ + #include "cs89x0.h" static char version[] __initdata = @@ -173,6 +178,10 @@ #include static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; +#elif defined(CONFIG_ARCH_MX1ADS) +static unsigned int netcard_portlist[] __initdata = + { IMX_CS4_VIRT, 0}; +static unsigned int cs8900_irq_map[] = {13, 0, 0, 0}; #else static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; @@ -403,6 +412,27 @@ return -1; } +#ifdef CONFIG_ARCH_MX1ADS + +static void setup_default_data (struct net_device *dev) +{ + /* Default MAC address if EEPROM fails and no command line parameter */ + u16 MacAddr[3] = {0x0800, 0x09a2, 0xe20a}; + struct net_local *lp; + int i; + + lp = (struct net_local *)dev->priv; + + for (i=0; i < ETH_ALEN/2; i++) { + dev->dev_addr[i*2] = MacAddr[i]; + dev->dev_addr[i*2+1] = MacAddr[i] >> 8; + } + + lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T; +} + +#endif /* CONFIG_MACH_MX1ADS */ + /* This is the real probe routine. Linux has a history of friendly device probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. @@ -604,7 +634,12 @@ } else #endif if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0) + { printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n"); +#ifdef CONFIG_ARCH_MX1ADS + setup_default_data(dev); +#endif /* CONFIG_MACH_MX1ADS */ + } else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n"); } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { Index: drivers/net/cs89x0.h =================================================================== --- a/drivers/net/cs89x0.h (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/net/cs89x0.h (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -446,6 +446,8 @@ #define PNP_IRQ_FRMT 0x0022 /* PNP small item IRQ format */ #ifdef CONFIG_SH_HICOSH4 #define CS8900_IRQ_MAP 0x0002 /* HiCO-SH4 board has its IRQ on #1 */ +#elif defined(CONFIG_MACH_MX1ADS) +#define CS8900_IRQ_MAP (1<<13) /* MX1ADS board has cs890x hooked on to IRQ13 */ #else #define CS8900_IRQ_MAP 0x1c20 /* This IRQ map is fixed */ #endif Index: drivers/parport/Kconfig =================================================================== --- a/drivers/parport/Kconfig (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/parport/Kconfig (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -92,6 +92,10 @@ tristate "Archimedes hardware" depends on ARM && PARPORT +config PARPORT_MX1FS2 + tristate "mx1fs2 hardware" + depends on MACH_MX1FS2 && PARPORT + config PARPORT_AMIGA tristate "Amiga builtin port" depends on AMIGA && PARPORT Index: drivers/parport/parport_mx1fs2.c =================================================================== --- a/drivers/parport/parport_mx1fs2.c (revision 0) +++ b/drivers/parport/parport_mx1fs2.c (revision 490) @@ -0,0 +1,281 @@ +/* Low-level parallel port routines for Archimedes onboard hardware + * + * Author: Phil Blundell + */ + +/* This driver is for the parallel port hardware found on Acorn's old + * range of Archimedes machines. The A5000 and newer systems have PC-style + * I/O hardware and should use the parport_pc driver instead. + * + * The Acorn printer port hardware is very simple. There is a single 8-bit + * write-only latch for the data port and control/status bits are handled + * with various auxilliary input and output lines. The port is not + * bidirectional, does not support any modes other than SPP, and has only + * a subset of the standard printer control lines connected. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#undef DEBUG +#ifdef DEBUG +#define DPRINTK(x...) printk(x) +#else +#define DPRINTK(x...) do { } while (0) +#endif + +#define __LPT(offs) *( (volatile u8 *) (((u32)(MX1FS2_LPT_VIRT)) + (offs))) + +/* register map of 16C552 parport */ +#define PARPORT_DR 0 +#define PARPORT_SR 1 +#define PARPORT_CON 2 + +#define SR_BUSY (1<<7) +#define SR_ACK (1<<6) +#define SR_PAPEROUT (1<<5) +#define SR_SELECT (1<<4) +#define SR_ERROR (1<<3) +#define SR_IRQ (1<<2) + +#define COM_INTP_EN (1<<4) +#define COM_SLCTIN (1<<3) +#define COM_INIT (1<<2) +#define COM_AUTO_FDXT (1<<1) +#define COM_STROBE (1<<0) + +#define CON_IN_OUT (1<<5) +#define CON_INTP_EN (1<<4) +#define CON_SELECT (1<<3) +#define CON_INIT (1<<2) +#define CON_AUTOFD (1<<1) +#define CON_STROBE (1<<0) + +static struct parport *this_port; + +static void mx1fs2_enable_irq(struct parport *p) +{ + printk("parport mx1fs2: %s not implemented\n",__FUNCTION__); + enable_irq(p->irq); +} + +static void mx1fs2_disable_irq(struct parport *p) +{ + printk("parport mx1fs2: %s not implemented\n",__FUNCTION__); + disable_irq(p->irq); +} + +static void mx1fs2_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + DPRINTK(KERN_DEBUG "parport mx1fs2: %s not implemented\n",__FUNCTION__); + parport_generic_irq(irq, (struct parport *) dev_id, regs); +} + +static void mx1fs2_write_data(struct parport *p, unsigned char data) +{ + DPRINTK(KERN_DEBUG "%s data: 0x%02x\n",__FUNCTION__,data); + __LPT(PARPORT_DR) = data; +} + +static unsigned char mx1fs2_read_data(struct parport *p) +{ + u8 data; + + data = __LPT(PARPORT_DR); + DPRINTK(KERN_DEBUG "%s data: 0x%02x\n",__FUNCTION__,data); + return __LPT(PARPORT_DR); +} + +static int control = 0; + +static void mx1fs2_write_control(struct parport *p, unsigned char control) +{ + u8 con, mask; + + con = 0; + DPRINTK(KERN_DEBUG "%s control: 0x%02x\n",__FUNCTION__,control); + + mask = + PARPORT_CONTROL_STROBE | PARPORT_CONTROL_AUTOFD | + PARPORT_CONTROL_INIT | PARPORT_CONTROL_SELECT; + con &= ~mask; + con |= control & mask; + + control = con; + __LPT(PARPORT_CON) = con; + udelay(5); +} + +static unsigned char mx1fs2_read_control(struct parport *p) +{ + DPRINTK(KERN_DEBUG "%s control: 0x%02x\n",__FUNCTION__,control); + return control; +} + +static unsigned char mx1fs2_read_status(struct parport *p) +{ + unsigned char status; + unsigned char mask; + + status = __LPT(PARPORT_SR); + DPRINTK(KERN_DEBUG "%s status: 0x%02x\n",__FUNCTION__,control); + + mask = SR_ERROR | SR_SELECT | SR_PAPEROUT | SR_ACK | SR_BUSY; + + return (status & mask); +} + +static void mx1fs2_data_forward(struct parport *p) +{ + control &= ~CON_IN_OUT; + __LPT(PARPORT_CON) = control; +} + +static void mx1fs2_data_reverse(struct parport *p) +{ + control |= CON_IN_OUT; + __LPT(PARPORT_CON) = control; +} + +static void mx1fs2_init_state(struct pardevice *dev, + struct parport_state *s) +{ + s->u.pc.ctr = 0xc; +} + +static void mx1fs2_save_state(struct parport *p, struct parport_state *s) +{ + s->u.pc.ctr = control; +} + +static void mx1fs2_restore_state(struct parport *p, struct parport_state *s) +{ + control = s->u.pc.ctr; + __LPT(PARPORT_CON) = control; + udelay(5); +} + +static __inline__ unsigned char mx1fs2_frob_control (struct parport *p, + unsigned char mask, + unsigned char val) +{ + unsigned char ctr = control; + const unsigned char wm = (PARPORT_CONTROL_STROBE | + PARPORT_CONTROL_AUTOFD | + PARPORT_CONTROL_INIT | + PARPORT_CONTROL_SELECT); + + DPRINTK(KERN_DEBUG "%s mask: 0x%02x val: 0x%02x\n",__FUNCTION__,mask,val); + /* Take this out when drivers have adapted to newer interface. */ + if (mask & 0x20) { + DPRINTK (KERN_DEBUG "%s (%s): use data_%s for this!\n", + p->name, p->cad->name, + (val & 0x20) ? "reverse" : "forward"); + if (val & 0x20) + mx1fs2_data_reverse (p); + else + mx1fs2_data_forward (p); + } + + /* Restrict mask and val to control lines. */ + mask &= wm; + val &= wm; + + ctr = (ctr & ~mask) ^ val; + __LPT(PARPORT_CON) = ctr; + control = ctr; /* Update soft copy */ + + return ctr; +} + +static struct parport_operations parport_mx1fs2_ops = +{ + .write_data = mx1fs2_write_data, + .read_data = mx1fs2_read_data, + + .write_control = mx1fs2_write_control, + .read_control = mx1fs2_read_control, + .frob_control = mx1fs2_frob_control, + + .read_status = mx1fs2_read_status, + + .enable_irq = mx1fs2_enable_irq, + .disable_irq = mx1fs2_disable_irq, + + .data_forward = mx1fs2_data_forward, + .data_reverse = mx1fs2_data_reverse, + + .init_state = mx1fs2_init_state, + .save_state = mx1fs2_save_state, + .restore_state = mx1fs2_restore_state, + + .epp_write_data = parport_ieee1284_epp_write_data, + .epp_read_data = parport_ieee1284_epp_read_data, + .epp_write_addr = parport_ieee1284_epp_write_addr, + .epp_read_addr = parport_ieee1284_epp_read_addr, + + .ecp_write_data = parport_ieee1284_ecp_write_data, + .ecp_read_data = parport_ieee1284_ecp_read_data, + .ecp_write_addr = parport_ieee1284_ecp_write_addr, + + .compat_write_data = parport_ieee1284_write_compat, + .nibble_read_data = parport_ieee1284_read_nibble, + .byte_read_data = parport_ieee1284_read_byte, + + .owner = THIS_MODULE, +}; + +/* --- Initialisation code -------------------------------- */ + +int __init parport_mx1fs2_init(void) +{ + struct parport *p; + struct resource *res; + char *fake_name = "parport probe"; + + printk("mx1fs2 parport driver\n"); + + res = request_mem_region(MX1FS2_LPT_VIRT, 4, fake_name); + if (res == NULL) + return 0; + + p = parport_register_port (MX1FS2_LPT_VIRT, PARPORT_IRQ_NONE, + PARPORT_DMA_NONE, &parport_mx1fs2_ops); + + if (!p) { + release_mem_region(MX1FS2_LPT_VIRT, 4); + return 0; + } + + this_port = p; + rename_region(res, p->name); + + printk(KERN_INFO "registered mx1fs2 parport driver\n"); + + /* Tell the high-level drivers about the port. */ + parport_announce_port (p); + + return 1; +} + +void __exit parport_mx1fs2_exit(void) +{ + parport_remove_port(this_port); + parport_put_port(this_port); + release_mem_region(MX1FS2_LPT_VIRT, 4); +} + +module_init(parport_mx1fs2_init) +module_exit(parport_mx1fs2_exit) Index: drivers/parport/Makefile =================================================================== --- a/drivers/parport/Makefile (.../vanilla/linux-2.6.10) (revision 490) +++ b/drivers/parport/Makefile (.../linux-imx/releases/linux-2.6.10-imx1) (revision 490) @@ -17,3 +17,4 @@ obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o +obj-$(CONFIG_PARPORT_MX1FS2) += parport_mx1fs2.o