diff -urN linux-2.6.32.56.org/arch/mips/Kconfig linux-2.6.32.56/arch/mips/Kconfig --- linux-2.6.32.56.org/arch/mips/Kconfig 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/Kconfig 2012-02-14 23:59:14.000000000 +0900 @@ -740,6 +740,21 @@ config GENERIC_HARDIRQS_NO__DO_IRQ def_bool y +config OMS400_PUSHSW + bool + depends on MIPS && MIPS_OMS400 + default y + +config OMS400_LED + bool + depends on MIPS && MIPS_OMS400 + default y + +config OMS400_DIO + bool + depends on MIPS && MIPS_OMS400 + default y + # # Select some configuration options automatically based on user selections. # @@ -1929,15 +1944,24 @@ config HZ_100 bool "100 HZ" if SYS_SUPPORTS_100HZ || SYS_SUPPORTS_ARBIT_HZ + config HZ_125 + bool "125 HZ" if SYS_SUPPORTS_125HZ + config HZ_128 bool "128 HZ" if SYS_SUPPORTS_128HZ || SYS_SUPPORTS_ARBIT_HZ + config HZ_200 + bool "200 HZ" if SYS_SUPPORTS_200HZ + config HZ_250 bool "250 HZ" if SYS_SUPPORTS_250HZ || SYS_SUPPORTS_ARBIT_HZ config HZ_256 bool "256 HZ" if SYS_SUPPORTS_256HZ || SYS_SUPPORTS_ARBIT_HZ + config HZ_500 + bool "500 HZ" if SYS_SUPPORTS_500HZ + config HZ_1000 bool "1000 HZ" if SYS_SUPPORTS_1000HZ || SYS_SUPPORTS_ARBIT_HZ @@ -1952,15 +1976,24 @@ config SYS_SUPPORTS_100HZ bool +config SYS_SUPPORTS_125HZ + bool + config SYS_SUPPORTS_128HZ bool +config SYS_SUPPORTS_200HZ + bool + config SYS_SUPPORTS_250HZ bool config SYS_SUPPORTS_256HZ bool +config SYS_SUPPORTS_500HZ + bool + config SYS_SUPPORTS_1000HZ bool @@ -1978,9 +2011,12 @@ int default 48 if HZ_48 default 100 if HZ_100 + default 125 if HZ_125 default 128 if HZ_128 + default 200 if HZ_200 default 250 if HZ_250 default 256 if HZ_256 + default 500 if HZ_500 default 1000 if HZ_1000 default 1024 if HZ_1024 diff -urN linux-2.6.32.56.org/arch/mips/Makefile linux-2.6.32.56/arch/mips/Makefile --- linux-2.6.32.56.org/arch/mips/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/Makefile 2012-02-16 00:18:28.000000000 +0900 @@ -259,6 +259,13 @@ load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000 +# +# Plathome OMS-AL400/128 +# +core-$(CONFIG_MIPS_OMS400) += arch/mips/alchemy/devboards/ +cflags-$(CONFIG_MIPS_OMS400) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 +load-$(CONFIG_MIPS_OMS400) += 0xffffffff80100000 + # # AMD Alchemy Db1200 eval board # core-$(CONFIG_MIPS_DB1200) += arch/mips/alchemy/devboards/ diff -urN linux-2.6.32.56.org/arch/mips/alchemy/Kconfig linux-2.6.32.56/arch/mips/alchemy/Kconfig --- linux-2.6.32.56.org/arch/mips/alchemy/Kconfig 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/alchemy/Kconfig 2012-02-14 23:34:54.000000000 +0900 @@ -64,6 +64,25 @@ select MIPS_DISABLE_OBSOLETE_IDE select SYS_SUPPORTS_LITTLE_ENDIAN +config MIPS_OMS400 + bool "Plat'Home Open Micro Server based on AU1550/400" + select SOC_AU1550 + select HW_HAS_PCI + select DMA_NONCOHERENT + select MIPS_DISABLE_OBSOLETE_IDE + select RESOURCES_64BIT if PCI + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_LITTLE_ENDIAN + select OMS400_PUSHSW + select OMS400_LED + select OMS400_DIO + select SYS_SUPPORTS_100HZ + select SYS_SUPPORTS_125HZ + select SYS_SUPPORTS_200HZ + select SYS_SUPPORTS_250HZ + select SYS_SUPPORTS_500HZ + select SYS_SUPPORTS_1000HZ + config MIPS_MIRAGE bool "Alchemy Mirage board" select DMA_NONCOHERENT diff -urN linux-2.6.32.56.org/arch/mips/alchemy/common/platform.c linux-2.6.32.56/arch/mips/alchemy/common/platform.c --- linux-2.6.32.56.org/arch/mips/alchemy/common/platform.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/alchemy/common/platform.c 2012-02-14 23:50:15.000000000 +0900 @@ -46,9 +46,14 @@ PORT(UART1_ADDR, AU1100_UART1_INT), PORT(UART3_ADDR, AU1100_UART3_INT), #elif defined(CONFIG_SOC_AU1550) +#ifdef CONFIG_MIPS_OMS400 + PORT(UART0_ADDR, AU1550_UART0_INT), + PORT(UART3_ADDR, AU1550_UART3_INT), +#else PORT(UART0_ADDR, AU1550_UART0_INT), PORT(UART1_ADDR, AU1550_UART1_INT), PORT(UART3_ADDR, AU1550_UART3_INT), +#endif #elif defined(CONFIG_SOC_AU1200) PORT(UART0_ADDR, AU1200_UART0_INT), PORT(UART1_ADDR, AU1200_UART1_INT), @@ -66,6 +71,7 @@ }; /* OHCI (USB full speed host controller) */ +#ifndef CONFIG_MIPS_OMS400 static struct resource au1xxx_usb_ohci_resources[] = { [0] = { .start = USB_OHCI_BASE, @@ -92,6 +98,7 @@ .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources), .resource = au1xxx_usb_ohci_resources, }; +#endif /*** AU1100 LCD controller ***/ @@ -333,7 +340,9 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { &au1xx0_uart_device, +#ifndef CONFIG_MIPS_OMS400 &au1xxx_usb_ohci_device, +#endif &au1x00_pcmcia_device, #ifdef CONFIG_FB_AU1100 &au1100_lcd_device, diff -urN linux-2.6.32.56.org/arch/mips/alchemy/common/reset.c linux-2.6.32.56/arch/mips/alchemy/common/reset.c --- linux-2.6.32.56.org/arch/mips/alchemy/common/reset.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/alchemy/common/reset.c 2012-02-15 00:06:25.000000000 +0900 @@ -32,6 +32,12 @@ #include #include +#if defined(CONFIG_MIPS_OMS400) && defined(CONFIG_OMS400_LED) +#include +#define BLINK_MSEC (1000) +extern int obsled_out(int); +#endif + void au1000_restart(char *command) { /* Set all integrated peripherals to disabled states */ @@ -161,6 +167,16 @@ while (1); /* should not get here */ #else printk(KERN_NOTICE "\n** You can safely turn off the power\n"); +#if defined(CONFIG_MIPS_OMS400) && defined(CONFIG_OMS400_LED) + while(1) { + obsled_out(7); + au_sync(); + mdelay(BLINK_MSEC); + obsled_out(0); + au_sync(); + mdelay(BLINK_MSEC); + } +#endif #ifdef CONFIG_MIPS_MIRAGE gpio_direction_output(210, 1); #endif diff -urN linux-2.6.32.56.org/arch/mips/alchemy/devboards/Makefile linux-2.6.32.56/arch/mips/alchemy/devboards/Makefile --- linux-2.6.32.56.org/arch/mips/alchemy/devboards/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/alchemy/devboards/Makefile 2012-02-16 00:56:20.000000000 +0900 @@ -14,5 +14,6 @@ obj-$(CONFIG_MIPS_DB1200) += pb1200/ obj-$(CONFIG_MIPS_DB1500) += db1x00/ obj-$(CONFIG_MIPS_DB1550) += db1x00/ +obj-$(CONFIG_MIPS_OMS400) += db1x00/ obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/ obj-$(CONFIG_MIPS_MIRAGE) += db1x00/ diff -urN linux-2.6.32.56.org/arch/mips/alchemy/devboards/db1x00/board_setup.c linux-2.6.32.56/arch/mips/alchemy/devboards/db1x00/board_setup.c --- linux-2.6.32.56.org/arch/mips/alchemy/devboards/db1x00/board_setup.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/alchemy/devboards/db1x00/board_setup.c 2012-02-15 00:16:00.000000000 +0900 @@ -36,7 +36,9 @@ #include +#ifndef CONFIG_MIPS_OMS400 static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; +#endif const char *get_system_type(void) { @@ -50,7 +52,9 @@ void board_reset(void) { /* Hit BCSR.SW_RESET[RESET] */ +#ifndef CONFIG_MIPS_OMS400 bcsr->swreset = 0x0000; +#endif } void __init board_setup(void) @@ -96,7 +100,9 @@ au_sync(); } #endif +#ifndef CONFIG_MIPS_OMS400 bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */ +#endif /* Enable GPIO[31:0] inputs */ alchemy_gpio1_input_enable(); @@ -145,4 +151,7 @@ #ifdef CONFIG_MIPS_DB1550 printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n"); #endif +#ifdef CONFIG_MIPS_OMS400 + printk("Plat'Home OMS-AL400/128 based on AMD Alchemy Au1550/400\n"); +#endif } diff -urN linux-2.6.32.56.org/arch/mips/alchemy/devboards/db1x00/irqmap.c linux-2.6.32.56/arch/mips/alchemy/devboards/db1x00/irqmap.c --- linux-2.6.32.56.org/arch/mips/alchemy/devboards/db1x00/irqmap.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/alchemy/devboards/db1x00/irqmap.c 2012-02-15 01:01:18.000000000 +0900 @@ -62,10 +62,23 @@ }; #endif +#ifdef CONFIG_MIPS_OMS400 +char irq_tab_alchemy[][5] __initdata = { + [1] = { -1, INTD, INTD, INTD, INTD}, /* External PCI slot */ + [2] = { -1, INTC, INTC, INTC, INTX}, /* uPD720101 USB */ + [3] = { -1, INTB, INTX, INTX, INTX}, /* E1000 GBEther */ + [4] = { -1, INTA, INTX, INTX, INTX}, /* E1000 GBEther */ +}; +#endif struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { #ifndef CONFIG_MIPS_MIRAGE +#ifdef CONFIG_MIPS_OMS400 + { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */ + { AU1000_GPIO_15,IRQF_TRIGGER_HIGH,0 }, /* PUSH BUTTON IRQ# */ + { AU1500_GPIO_201_205,(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING),0}, /* DIO in */ +#else #ifdef CONFIG_MIPS_DB1550 { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */ { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */ @@ -78,6 +91,7 @@ { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */ { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */ #endif +#endif #else { AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */ #endif diff -urN linux-2.6.32.56.org/arch/mips/include/asm/dio_oms400.h linux-2.6.32.56/arch/mips/include/asm/dio_oms400.h --- linux-2.6.32.56.org/arch/mips/include/asm/dio_oms400.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/arch/mips/include/asm/dio_oms400.h 2012-02-14 12:01:36.000000000 +0900 @@ -0,0 +1,20 @@ +/* + * 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. + * + * Copyright (C) 1995, 1996, 2001 Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#ifndef _DIO_OMS400_H +#define _DIO_OMS400_H + +#include + +#define DIOIOC_RD_DIN _IOR('D', 0x31, int) +#define DIOIOC_WT_DOUT _IOW('D', 0x32, int) +#define DIOIOC_RD_DOUT _IOR('D', 0x33, int) +#define DIOIOC_WAITCHANGE _IOR('D', 0x34, int) +#define DIOIOC_GETWAITPID _IOR('D', 0x35, int) + +#endif /* _DOI_OMS400_H */ diff -urN linux-2.6.32.56.org/arch/mips/include/asm/mach-au1x00/au1xxx.h linux-2.6.32.56/arch/mips/include/asm/mach-au1x00/au1xxx.h --- linux-2.6.32.56.org/arch/mips/include/asm/mach-au1x00/au1xxx.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/include/asm/mach-au1x00/au1xxx.h 2012-02-15 13:47:47.000000000 +0900 @@ -26,7 +26,8 @@ #include #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \ - defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) + defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || \ + defined(CONFIG_MIPS_OMS400) #include #elif defined(CONFIG_MIPS_PB1550) diff -urN linux-2.6.32.56.org/arch/mips/include/asm/mach-db1x00/db1x00.h linux-2.6.32.56/arch/mips/include/asm/mach-db1x00/db1x00.h --- linux-2.6.32.56.org/arch/mips/include/asm/mach-db1x00/db1x00.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/include/asm/mach-db1x00/db1x00.h 2012-02-15 13:54:55.000000000 +0900 @@ -29,6 +29,7 @@ #include +#ifndef CONFIG_MIPS_OMS400 #ifdef CONFIG_MIPS_DB1550 #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX @@ -176,4 +177,9 @@ #define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */ #define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */ +#else + +#define SMBUS_PSC_BASE PSC0_BASE_ADDR + +#endif /* CONFIG_MIPS_OMS400 */ #endif /* __ASM_DB1X00_H */ diff -urN linux-2.6.32.56.org/arch/mips/include/asm/pushsw_oms400.h linux-2.6.32.56/arch/mips/include/asm/pushsw_oms400.h --- linux-2.6.32.56.org/arch/mips/include/asm/pushsw_oms400.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/arch/mips/include/asm/pushsw_oms400.h 2012-02-14 12:01:36.000000000 +0900 @@ -0,0 +1,19 @@ +/* + * Century + * - Century's push switch driver header + */ + +#include +#include +/* #include */ + +#define PUSHSW_MAJOR (MISC_MAJOR) + +#define PUSHSW_IOCTL_BASE 'P' + +#define PSWIOC_GETSTATUS _IOR(PUSHSW_IOCTL_BASE, 0, int) +#define PSWIOC_WAITPUSH _IOR(PUSHSW_IOCTL_BASE, 1, int) +#define PSWIOC_GETWAITPID _IOR(PUSHSW_IOCTL_BASE, 2, int) + +#define PSWIOF_PUSHED (1) +#define PSWIOF_NOTPUSHED (0) diff -urN linux-2.6.32.56.org/arch/mips/include/asm/unistd.h linux-2.6.32.56/arch/mips/include/asm/unistd.h --- linux-2.6.32.56.org/arch/mips/include/asm/unistd.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/include/asm/unistd.h 2012-02-15 13:59:12.000000000 +0900 @@ -994,10 +994,9 @@ #define __NR_N32_Linux 6000 #define __NR_N32_Linux_syscalls 299 -#ifdef __KERNEL__ - #ifndef __ASSEMBLY__ +#ifdef __KERNEL__ #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff -urN linux-2.6.32.56.org/arch/mips/kernel/setup.c linux-2.6.32.56/arch/mips/kernel/setup.c --- linux-2.6.32.56.org/arch/mips/kernel/setup.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/kernel/setup.c 2012-02-15 09:23:20.000000000 +0900 @@ -169,6 +169,9 @@ if (!initrd_start || initrd_end <= initrd_start) { #ifdef CONFIG_PROBE_INITRD_HEADER u32 *initrd_header; +#ifdef CONFIG_MIPS_OMS400 + extern u32 Initrd_Data; +#endif /* * See if initrd has been added to the kernel image by @@ -177,11 +180,19 @@ * word is a magic number and the second one is the size of * initrd. Initrd start must be page aligned in any cases. */ +#ifdef CONFIG_MIPS_OMS400 + initrd_header = &Initrd_Data; + if (initrd_header[0] != 0x494E5244) + goto disable; + initrd_start = initrd_header[1]; + initrd_end = initrd_header[2]; +#else initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; if (initrd_header[0] != 0x494E5244) goto disable; initrd_start = (unsigned long)(initrd_header + 2); initrd_end = initrd_start + initrd_header[1]; +#endif #else goto disable; #endif diff -urN linux-2.6.32.56.org/arch/mips/kernel/vmlinux.lds.S linux-2.6.32.56/arch/mips/kernel/vmlinux.lds.S --- linux-2.6.32.56.org/arch/mips/kernel/vmlinux.lds.S 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/kernel/vmlinux.lds.S 2012-02-15 23:10:13.000000000 +0900 @@ -112,6 +112,12 @@ __init_end = .; /* freed after init ends here */ +#ifdef CONFIG_MIPS_OMS400 + . = ALIGN(PAGE_SIZE); + .initrd_data : { *(.initrd_data) } + . = ALIGN(PAGE_SIZE); +#endif + BSS_SECTION(0, 0, 0) _end = . ; diff -urN linux-2.6.32.56.org/arch/mips/mm/init.c linux-2.6.32.56/arch/mips/mm/init.c --- linux-2.6.32.56.org/arch/mips/mm/init.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/arch/mips/mm/init.c 2012-02-15 09:29:28.000000000 +0900 @@ -438,7 +438,7 @@ ClearPageReserved(page); init_page_count(page); - memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset(addr, 0x00, PAGE_SIZE); __free_page(page); totalram_pages++; } diff -urN linux-2.6.32.56.org/drivers/Makefile linux-2.6.32.56/drivers/Makefile --- linux-2.6.32.56.org/drivers/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/Makefile 2012-02-15 09:39:38.000000000 +0900 @@ -40,6 +40,7 @@ obj-$(CONFIG_PARPORT) += parport/ obj-y += base/ block/ misc/ mfd/ obj-$(CONFIG_NUBUS) += nubus/ +obj-$(CONFIG_PCCARD) += pcmcia/ obj-y += macintosh/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_SCSI) += scsi/ @@ -54,7 +55,7 @@ obj-$(CONFIG_UIO) += uio/ obj-y += cdrom/ obj-y += auxdisplay/ -obj-$(CONFIG_PCCARD) += pcmcia/ +#obj-$(CONFIG_PCCARD) += pcmcia/ obj-$(CONFIG_DIO) += dio/ obj-$(CONFIG_SBUS) += sbus/ obj-$(CONFIG_ZORRO) += zorro/ diff -urN linux-2.6.32.56.org/drivers/char/Makefile linux-2.6.32.56/drivers/char/Makefile --- linux-2.6.32.56.org/drivers/char/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/char/Makefile 2012-02-15 09:44:08.000000000 +0900 @@ -98,6 +98,9 @@ obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o obj-$(CONFIG_GPIO_TB0219) += tb0219.o obj-$(CONFIG_TELCLOCK) += tlclk.o +obj-$(CONFIG_OMS400_PUSHSW) += pushsw_oms400.o +obj-$(CONFIG_OMS400_LED) += led_oms400.o +obj-$(CONFIG_OMS400_DIO) += dio_oms400.o obj-$(CONFIG_MWAVE) += mwave/ obj-$(CONFIG_AGP) += agp/ diff -urN linux-2.6.32.56.org/drivers/char/dio_oms400.c linux-2.6.32.56/drivers/char/dio_oms400.c --- linux-2.6.32.56.org/drivers/char/dio_oms400.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/drivers/char/dio_oms400.c 2012-02-15 19:11:20.000000000 +0900 @@ -0,0 +1,198 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DBGON(x) x +#define DBGOFF(x) + +#define DIO_VER "0.01" +#define DIO_IRQ AU1500_GPIO_201_205 + +/*---------------------------------------------------------------------------- + * Prototypes. + *----------------------------------------------------------------------------*/ +int dio_init(void); +irqreturn_t dio_isr(int irq, void *dev_id, struct pt_regs *regs); +static int dio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int dio_open(struct inode *inode, struct file *file); +static int dio_release(struct inode *inode, struct file *file); + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static struct file_operations dio_fops = { + owner: THIS_MODULE, + ioctl: dio_ioctl, + open: dio_open, + release: dio_release, +}; +static struct miscdevice dio_miscdev = + { OMS400DIO_MINOR, "dio", &dio_fops }; +static DECLARE_WAIT_QUEUE_HEAD(dio_wait); + +/* used to allow only one process at a time to "own" the DIO */ +static pid_t dio_wait_pid = 0; +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +int +dio_init(void) +{ + printk("DIO driver v%s\n", DIO_VER); + +#ifdef CONFIG_OMS400_DIO_ENABLE_IRQ + /* Install the DIO interrupt handler */ + if (request_irq(DIO_IRQ, dio_isr, IRQF_IRQPOLL, "dio", NULL)) { + printk("[dio_open] interrupt %u not free\n", DIO_IRQ); + return (-EIO); + } + DBGOFF(printk("[dio_init] DIO installed on interrupt %u\n", DIO_IRQ);) +#endif + misc_register(&dio_miscdev); + return (0); +} /* dio_init() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +irqreturn_t +dio_isr(int irq, void *dev_id, struct pt_regs *regs) +{ + /* DBGOFF(printk(KERN_CRIT "p");) */ + wake_up_interruptible(&dio_wait); + return IRQ_HANDLED; +} /* dio_isr() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static int +dio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned long flags; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; + int val, mask, err; + + if (MINOR(inode->i_rdev) != OMS400DIO_MINOR) { + return (-ENODEV); + } + + switch (cmd) { +#ifdef CONFIG_OMS400_DIO_ENABLE_IRQ + case DIOIOC_GETWAITPID: + return (put_user(dio_wait_pid, (int *) arg)); + case DIOIOC_WAITCHANGE: + /* protect dio_wait_pid */ + spin_lock_irqsave(&driver_lock, flags); + if (dio_wait_pid == 0) { + dio_wait_pid = current->pid; + spin_unlock_irqrestore(&driver_lock, flags); + DBGOFF(printk("[dio_ioctl] DIOIOC_WAITCHANGE pid %u\n", dio_wait_pid);) + /* block until DIN change */ + interruptible_sleep_on(&dio_wait); + spin_lock_irqsave(&driver_lock, flags); + dio_wait_pid = 0; + spin_unlock_irqrestore(&driver_lock, flags); + + DBGOFF(printk("[dio_ioctl] unblocked\n");) + if (signal_pending(current)) { + DBGOFF(printk("[dio_ioctl] sig\n");) + return (-ERESTARTSYS); + } + return (0); + } else { + spin_unlock_irqrestore(&driver_lock, flags); + return (-EBUSY); + } +#endif + case DIOIOC_RD_DIN: + return (put_user((au_readl(GPIO2_PINSTATE) >> 1) & 0x0f, (int *) arg)); + + case DIOIOC_WT_DOUT: + err = get_user(val, (int *) arg); + if (err) + return err; + mask = (val >> 16) & 0x0f; + val &= 0x0f; + au_writel ((val << 11) | (mask << 27), GPIO2_OUTPUT); + return 0; + case DIOIOC_RD_DOUT: + return (put_user((au_readl(GPIO2_PINSTATE) >> 11) & 0x0f, (int *) arg)); + default: + break; + } + return (-ENOIOCTLCMD); +} /* dio_ioctl() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static int +dio_open(struct inode *inode, struct file *file) +{ + switch (MINOR(inode->i_rdev)) { + case OMS400DIO_MINOR: +// MOD_INC_USE_COUNT; + return (0); + default: + return (-ENODEV); + } +} /* dio_open() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static int +dio_release(struct inode *inode, struct file *file) +{ + unsigned long flags; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; + + DBGOFF(printk("[dio_release] ");) + if (MINOR(inode->i_rdev) == OMS400DIO_MINOR) { + DBGOFF(printk("by pid %u\n", current->pid);) + spin_lock_irqsave(&driver_lock, flags); + if (dio_wait_pid && (dio_wait_pid == current->pid)) { + dio_wait_pid = 0; + spin_unlock_irqrestore(&driver_lock, flags); + DBGOFF(printk("cleared\n");) + } else { + spin_unlock_irqrestore(&driver_lock, flags); + DBGOFF(if (dio_wait_pid) printk("dio_wait_pid %u, current->pid %u\n", dio_wait_pid, current->pid);) + } +// MOD_DEC_USE_COUNT; + } + return (0); +} /* dio_release() */ + +static void +dio_exit(void) +{ + misc_deregister(&dio_miscdev); +#ifdef CONFIG_OMS400_DIO_ENABLE_IRQ + free_irq(DIO_IRQ, NULL); +#endif +} /* cleanup_module() */ +module_init(dio_init); +module_exit(dio_exit); diff -urN linux-2.6.32.56.org/drivers/char/generic_serial.c linux-2.6.32.56/drivers/char/generic_serial.c --- linux-2.6.32.56.org/drivers/char/generic_serial.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/char/generic_serial.c 2012-02-15 09:53:51.000000000 +0900 @@ -267,6 +267,8 @@ { struct gs_port *port; unsigned long flags; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; func_enter (); @@ -348,6 +350,7 @@ static void gs_shutdown_port (struct gs_port *port) { unsigned long flags; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; func_enter(); @@ -509,6 +512,7 @@ { unsigned long flags; struct gs_port *port; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; func_enter (); diff -urN linux-2.6.32.56.org/drivers/char/led_oms400.c linux-2.6.32.56/drivers/char/led_oms400.c --- linux-2.6.32.56.org/drivers/char/led_oms400.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/drivers/char/led_oms400.c 2012-02-15 19:10:55.000000000 +0900 @@ -0,0 +1,147 @@ +/* + * FILE NAME au1000_gpio.c + * + * BRIEF MODULE DESCRIPTION + * Driver for Alchemy Au1000 GPIO. + * + * Author: MontaVista Software, Inc. + * Steve Longerbeam + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION "0.01" + +#define OMSLED_MINOR SEGLED_MINOR + +static int is_open = 0; + +/* + * Return the pin state. Pins configured as outputs will return + * the output state, and pins configured as inputs (tri-stated) + * will return input pin state. + */ +static int oms400led_in(u32 *val) +{ + *val = (inl(SYS_PINSTATERD) >> 6) & 0x07; + return 0; +} + +/* + * Set/clear GPIO pins. Only available GPIOs will be affected. + */ +static int oms400led_out(u32 data) +{ + int set, clr; + set = (data & 0x07) << 6; + clr = set ^ (0x07 << 6); + + if (set) + au_writel(set, SYS_OUTPUTSET); + if (clr) + au_writel(clr, SYS_OUTPUTCLR); + return 0; +} + +static int oms400led_open(struct inode *inode, struct file *file) +{ + is_open = 1; + return 0; +} + +static int oms400led_release(struct inode *inode, struct file *file) +{ + is_open = 0; + return 0; +} + +static ssize_t oms400led_write(struct file *file, const char *buf, size_t count, + loff_t *ppos) +{ + int err, i, led; + + if (count <= 0) + return 0; + + for (i = 0; i < count; i++) { + err = get_user(led, buf + i); + if (err) + return err; + if ((led < '0' ) || (led > '7')) + continue; + err = oms400led_out(led); + if (err) + return err; + } + return count; +} + +static struct file_operations oms400led_fops = +{ + .owner = THIS_MODULE, + .write = oms400led_write, + .open = oms400led_open, + .release = oms400led_release, +}; + + +static struct miscdevice oms400led_miscdev = +{ + OMSLED_MINOR, + "oms400 led", + &oms400led_fops +}; + +int __init oms400led_init(void) +{ + misc_register(&oms400led_miscdev); + printk("OMS-AL400 LED driver, version %s\n", VERSION); + return 0; +} + +void __exit oms400led_exit(void) +{ + misc_deregister(&oms400led_miscdev); +} + +module_init(oms400led_init); +module_exit(oms400led_exit); + +int obsled_out(int val) +{ + int err; + + err = oms400led_out(val & 0x07); + return err; +} diff -urN linux-2.6.32.56.org/drivers/char/pushsw_oms400.c linux-2.6.32.56/drivers/char/pushsw_oms400.c --- linux-2.6.32.56.org/drivers/char/pushsw_oms400.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/drivers/char/pushsw_oms400.c 2012-02-15 19:10:02.000000000 +0900 @@ -0,0 +1,193 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define USE_DIN + +#define DBGON(x) +#define DBGOFF(x) x + +#define PSW_VER "0.02" +#ifdef USE_DIN +#define PSW_IRQ AU1500_GPIO_201_205 +#define DIO_MASK 2 +#define DIO_CHECKV 0 +#else +#define PSW_IRQ AU1000_GPIO_15 +#endif + +/*---------------------------------------------------------------------------- + * Prototypes. + *----------------------------------------------------------------------------*/ +int psw_init(void); +irqreturn_t psw_isr(int irq, void *dev_id); +static int psw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int psw_open(struct inode *inode, struct file *file); +static int psw_release(struct inode *inode, struct file *file); + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static struct file_operations psw_fops = { + owner: THIS_MODULE, + ioctl: psw_ioctl, + open: psw_open, + release: psw_release, +}; +static struct miscdevice psw_miscdev = + { PUSHSW_MINOR, "pushsw", &psw_fops }; +static DECLARE_WAIT_QUEUE_HEAD(psw_wait); + +/* used to allow only one process at a time to "own" the push switch */ +static pid_t psw_wait_pid = 0; +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +int +psw_init(void) +{ + printk("Push switch driver v%s\n", PSW_VER); + + /* Install the push switch interrupt handler */ + if (request_irq(PSW_IRQ, psw_isr, IRQF_IRQPOLL, "push switch", NULL)) { + printk("[psw_open] interrupt %u not free\n", PSW_IRQ); + return (-EIO); + } + DBGOFF(printk("[psw_init] Push switch installed on interrupt %u\n", PSW_IRQ);) + misc_register(&psw_miscdev); + return (0); +} /* psw_init() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +irqreturn_t +psw_isr(int irq, void *dev_id) +{ + /* DBGOFF(printk(KERN_CRIT "p");) */ + wake_up_interruptible(&psw_wait); + return IRQ_HANDLED; +} /* psw_isr() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static int +psw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned long flags; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; + + if (MINOR(inode->i_rdev) != PUSHSW_MINOR) { + return (-ENODEV); + } + + switch (cmd) { + case PSWIOC_GETWAITPID: + return (put_user(psw_wait_pid, (int *) arg)); + case PSWIOC_WAITPUSH: + /* protect psw_wait_pid */ + spin_lock_irqsave(&driver_lock, flags); + if (psw_wait_pid == 0) { + psw_wait_pid = current->pid; + spin_unlock_irqrestore(&driver_lock, flags); + DBGOFF(printk("[psw_ioctl] PSWIOC_WAITPUSH pid %u\n", psw_wait_pid);) + /* block until switch pushed */ + while (1) { + interruptible_sleep_on(&psw_wait); +#ifdef USE_DIN + msleep(5); + if ((au_readl(GPIO2_PINSTATE) & DIO_MASK) == DIO_CHECKV) +#endif + break; + } + spin_lock_irqsave(&driver_lock, flags); + psw_wait_pid = 0; + spin_unlock_irqrestore(&driver_lock, flags); + + DBGOFF(printk("[psw_ioctl] unblocked\n");) + if (signal_pending(current)) { + DBGOFF(printk("[psw_ioctl] sig\n");) + return (-ERESTARTSYS); + } + return (0); + } else { + spin_unlock_irqrestore(&driver_lock, flags); + return (-EBUSY); + } + default: + break; + } + return (-ENOIOCTLCMD); +} /* psw_ioctl() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static int +psw_open(struct inode *inode, struct file *file) +{ + switch (MINOR(inode->i_rdev)) { + case PUSHSW_MINOR: +// MOD_INC_USE_COUNT; + return (0); + default: + return (-ENODEV); + } +} /* psw_open() */ + +/*---------------------------------------------------------------------------- + *----------------------------------------------------------------------------*/ +static int +psw_release(struct inode *inode, struct file *file) +{ + unsigned long flags; + spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; + + DBGOFF(printk("[psw_release] ");) + if (MINOR(inode->i_rdev) == PUSHSW_MINOR) { + DBGOFF(printk("by pid %u\n", current->pid);) + spin_lock_irqsave(&driver_lock, flags); + if (psw_wait_pid && (psw_wait_pid == current->pid)) { + psw_wait_pid = 0; + spin_unlock_irqrestore(&driver_lock, flags); + DBGOFF(printk("cleared\n");) + } else { + spin_unlock_irqrestore(&driver_lock, flags); + DBGOFF(if (psw_wait_pid) printk("psw_wait_pid %u, current->pid %u\n", psw_wait_pid, current->pid);) + } +// MOD_DEC_USE_COUNT; + } + return (0); +} /* psw_release() */ + +static void +psw_exit(void) +{ + misc_deregister(&psw_miscdev); + free_irq(PSW_IRQ, NULL); +} /* cleanup_module() */ +module_init(psw_init); +module_exit(psw_exit); diff -urN linux-2.6.32.56.org/drivers/i2c/busses/i2c-au1550.c linux-2.6.32.56/drivers/i2c/busses/i2c-au1550.c --- linux-2.6.32.56.org/drivers/i2c/busses/i2c-au1550.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/i2c/busses/i2c-au1550.c 2012-02-15 09:59:09.000000000 +0900 @@ -401,6 +401,7 @@ priv->ack_timeout = 200; priv->adap.nr = pdev->id; + priv->adap.class = I2C_CLASS_HWMON; priv->adap.algo = &au1550_algo; priv->adap.algo_data = priv; priv->adap.dev.parent = &pdev->dev; diff -urN linux-2.6.32.56.org/drivers/i2c/chips/Kconfig linux-2.6.32.56/drivers/i2c/chips/Kconfig --- linux-2.6.32.56.org/drivers/i2c/chips/Kconfig 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/i2c/chips/Kconfig 2012-02-15 10:03:08.000000000 +0900 @@ -16,6 +16,18 @@ This driver can also be built as a module. If so, the module will be called ds1682. +config OMS400_EEPROM + tristate "OMS400_EEPROM" + depends on I2C && MIPS_OMS400 + help + OMS-AL400/128 EEPROM driver. + +config OMS400_RTC + tristate "OMS400_RTC" + depends on I2C && MIPS_OMS400 + help + OMS-AL400/128 RTC driver. + config SENSORS_TSL2550 tristate "Taos TSL2550 ambient light sensor" depends on EXPERIMENTAL diff -urN linux-2.6.32.56.org/drivers/i2c/chips/Makefile linux-2.6.32.56/drivers/i2c/chips/Makefile --- linux-2.6.32.56.org/drivers/i2c/chips/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/i2c/chips/Makefile 2012-02-15 10:05:12.000000000 +0900 @@ -12,6 +12,8 @@ obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o +obj-$(CONFIG_OMS400_EEPROM) += eeprom-oms400.o +obj-$(CONFIG_OMS400_RTC) += r2025x-rtc.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff -urN linux-2.6.32.56.org/drivers/i2c/chips/eeprom-oms400.c linux-2.6.32.56/drivers/i2c/chips/eeprom-oms400.c --- linux-2.6.32.56.org/drivers/i2c/chips/eeprom-oms400.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/drivers/i2c/chips/eeprom-oms400.c 2012-02-15 21:10:21.000000000 +0900 @@ -0,0 +1,463 @@ +/* + * linux/drivers/i2c/chips/eeprom-oms400.c.c + * + * + * Copyright + * Author: 2002 AXE Inc. + * takawata@axe-inc.co.jp + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * TODO: + * - implement alarm and periodic IRQ support. + * + */ +/* + * Based On + * linux/drivers/char/x1226-rtc.c + * + * I2C Real Time Clock Client Driver for Xicor X1226 RTC/Calendar + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * TODO: + * - implement alarm and periodic IRQ support. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_MAJOR 240 +#define EEPROM_T_WR 10 +struct eepromi2c_private +{ + u8 ei2_addr; + int ei2_size; + int ei2_maxpage; + int use_count; + unsigned char *tmpbuf; + struct i2c_client *ei2_i2c; +}; + +static spinlock_t eeprom_state_lock = SPIN_LOCK_UNLOCKED; + +struct eepromi2c_private eepromi2c_conf[]= +{ + {0x50, 0x200, 16, 0, NULL, NULL, NULL}, +}; + +#define MAXEEPROMDEVS (sizeof(eepromi2c_conf)/ sizeof(struct eepromi2c_private)) +#ifndef I2C_M_WR +#define I2C_M_WR 0x0 +#endif + +#ifdef DEBUG_I2CEEPROM +#define dbg(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args) +#else +#define dbg(fmt, args...) +#endif + +#define I2CEEPROM_MODULE_NAME "LARGEEEPROM" +#define PFX I2CEEPROM_MODULE_NAME + +#define err(format, arg...) printk(KERN_ERR PFX ": " format , ## arg) +#define info(format, arg...) printk(KERN_INFO PFX ": " format , ## arg) +#define warn(format, arg...) printk(KERN_WARNING PFX ": " format , ## arg) +#define emerg(format, arg...) printk(KERN_EMERG PFX ": " format , ## arg) + +//yamamoto static struct i2c_driver i2ceeprom_driver; + +static int i2ceeprom_read(struct i2c_client *client, + u16 reg_offset, u8 *buf, int len) +{ + int ret; + u8 regbuf = reg_offset; + struct i2c_msg random_addr_read[2] = { + { + /* "Set Current Address" */ + client->addr, + client->flags | I2C_M_WR, + 1, + ®buf + }, + { + /* "Sequential Read" if len>1, + "Current Address Read" if len=1 */ + client->addr , + client->flags| I2C_M_RD , + len, + buf + } + }; + + random_addr_read[0].addr |= (reg_offset >> 8) &0x07;; + random_addr_read[1].addr |= (reg_offset >> 8) &0x07;; + + dbg("i2c_transfer %04x %04x\n",random_addr_read[0].addr,regbuf); + + if ((ret = i2c_transfer(client->adapter, random_addr_read, 2)) != 2) { + ret = -ENXIO; + dbg("i2c_transfer failed\n"); + } + + return ret; +} + +static int i2ceeprom_write(struct i2c_client *client, + u16 reg_offset, u8 *buf, int len) +{ + int ret; + u8* local_buf; + struct i2c_msg page_write = { + client->addr, + client->flags , + len + 1, + NULL + }; + + if ((local_buf = (u8*)kmalloc(len + 1, GFP_KERNEL)) == NULL) { + err("buffer alloc failed\n"); + return -ENOMEM; + } + + local_buf[0] = reg_offset; + memcpy(local_buf + 1, buf, len); + page_write.buf = local_buf; + + page_write.addr |= (reg_offset >> 8) &0x07; + dbg("i2c_transfer %04x %04x\n",page_write.addr,regbuf); + + if ((ret = i2c_transfer(client->adapter, &page_write, 1)) != 1) { + ret = -ENXIO; + dbg("i2c_transfer failed\n"); + } + + msleep(EEPROM_T_WR); + kfree(local_buf); + return ret; +} + +static long long eepromi2c_llseek(struct file *file, loff_t offset, int origin) +{ + int minor; + struct inode *minode = file->f_dentry->d_inode; + struct eepromi2c_private *pri; + + if ((minor = MINOR(minode->i_rdev)) >= MAXEEPROMDEVS) + return -ENXIO; + pri = &eepromi2c_conf[minor]; + switch (origin) { + case 0: + file->f_pos = offset; + return file->f_pos; + case 1: + file->f_pos += offset; + return file->f_pos; + case 2: + file->f_pos = pri->ei2_size - offset; + return file->f_pos; + default: + return -EINVAL; + } +} + +static ssize_t eepromi2c_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + int minor; + struct i2c_client *client; + struct eepromi2c_private *pri; + int offset, remaining, copysize; + struct inode *minode = file->f_dentry->d_inode; + if ((minor = MINOR(minode->i_rdev)) >= MAXEEPROMDEVS) + return -ENXIO; + pri = &eepromi2c_conf[minor]; + if (!(client = pri->ei2_i2c)) + return -ENXIO; + offset = *ppos; + offset += 16; + if ((offset + count) > pri->ei2_size) + count = pri->ei2_size - offset; + if (count <= 0) { + return 0; + } + remaining = count; + do { + copysize = (remaining > pri->ei2_maxpage) + ? pri->ei2_maxpage : remaining; + dbg("; copysize=%d\n", copysize); + i2ceeprom_read(client, offset, pri->tmpbuf, copysize); + if (copy_to_user(buf, pri->tmpbuf, copysize)) + return -EFAULT; + *ppos += copysize; + offset += copysize; + buf += copysize; + remaining -= copysize; + } while (remaining > 0); + return count; +} + +static ssize_t eepromi2c_write(struct file *file, const char *buf, size_t count, + loff_t *ppos) +{ + int minor; + struct i2c_client *client; + struct eepromi2c_private *pri; + int offset, remaining, copysize; + struct inode *minode = file->f_dentry->d_inode; + if ((minor = MINOR(minode->i_rdev)) >= MAXEEPROMDEVS) + return -ENXIO; + pri = &eepromi2c_conf[minor]; + if (!(client = pri->ei2_i2c)) + return -ENXIO; + offset = *ppos; + offset += 16; + if ((offset + count) > pri->ei2_size) + count = pri->ei2_size - offset; + if (count <= 0) { + return 0; + } + /*Write regeon should be aligned */ + copysize = (count > pri->ei2_maxpage) ? pri->ei2_maxpage : count; + if ((offset / pri->ei2_maxpage) != + ((offset + copysize) / pri->ei2_maxpage)) + copysize = pri->ei2_maxpage - (offset % pri->ei2_maxpage); + dbg("; offset=%d\n", offset); + remaining = count; + do { + dbg("; copysize=%d\n", copysize); + if (copy_from_user(pri->tmpbuf, buf, copysize)) { + return -EFAULT; + } + + i2ceeprom_write(client, offset, pri->tmpbuf, copysize); + *ppos += copysize; + offset += copysize; + buf += copysize; + remaining -= copysize; + copysize = (remaining > pri->ei2_maxpage) + ? pri->ei2_maxpage : remaining; + } while (remaining > 0); + return count; +} + +static int eepromi2c_open(struct inode *minode, struct file *mfile) +{ + int minor; + spin_lock(&eeprom_state_lock); + if ((minor = MINOR(minode->i_rdev)) >= MAXEEPROMDEVS) + return -ENXIO; + if (!eepromi2c_conf[minor].ei2_i2c) + return -ENXIO; + + if (eepromi2c_conf[minor].use_count) + return -EBUSY; + eepromi2c_conf[minor].use_count++; + spin_unlock(&eeprom_state_lock); + return 0; +} + +static int eepromi2c_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +static int eepromi2c_release(struct inode *inode, struct file *file) +{ + int minor; + spin_lock(&eeprom_state_lock); + if ((minor = MINOR(inode->i_rdev)) >= MAXEEPROMDEVS) + return -ENXIO; + eepromi2c_conf[minor].use_count--; + spin_unlock(&eeprom_state_lock); + return 0; +} + +static struct file_operations eepromi2c_fops = { + owner: THIS_MODULE, + llseek: eepromi2c_llseek, + read: eepromi2c_read, + write: eepromi2c_write, + ioctl: eepromi2c_ioctl, + open: eepromi2c_open, + release: eepromi2c_release, +}; + +//yamamoto --> +//yamamoto static int i2ceeprom_probe(struct i2c_adapter *adap) +static int i2ceeprom_probe(struct i2c_client *client, const struct i2c_device_id *id) +//yamamoto <-- +{ + int res, i; + int ret = 1; +#if 0 + char nbuffer[15]; +#endif + unsigned char stat; + struct i2c_client *this_client; + + res = -ENXIO; + register_chrdev(EEPROM_MAJOR, "eeprom", &eepromi2c_fops); + + this_client = kmalloc(sizeof(*this_client), GFP_KERNEL); + + for (i = 0; i < MAXEEPROMDEVS; i++) { + if (this_client == NULL) { + break; + } + + memset(this_client, 0, sizeof(*this_client)); + +//yamamoto --> + this_client = client; +//yamamoto <-- + +//yamamoto strcpy(this_client->name, I2CEEPROM_MODULE_NAME); +//yamamoto this_client->flags = 0; +//yamamoto this_client->addr = eepromi2c_conf[i].ei2_addr; +//yamamoto this_client->adapter = adap; +//yamamoto this_client->driver = &i2ceeprom_driver; + + if ((res = i2ceeprom_read(this_client, 0, &stat, 1)) < 0) { + printk("Probe read %d\n", res); + continue; + } + + if ((eepromi2c_conf[i].tmpbuf = + kmalloc(eepromi2c_conf[i].ei2_size, GFP_KERNEL)) == NULL) { + continue; + } + + printk("Serial EEPROM FOUND at %x\n", this_client->addr); +//yamamoto if (i2c_attach_client(this_client)) { +//yamamoto continue; +//yamamoto } + eepromi2c_conf[i].ei2_i2c = this_client; + ret = 0; /*At least 1 dev found */ + this_client = kmalloc(sizeof(*this_client), GFP_KERNEL); + } + kfree(this_client); + return ret; +} + +//yamamoto --> +//yamamoto static int i2ceeprom_detach(struct i2c_client *client) +static int i2ceeprom_remove(struct i2c_client *client) +//yamamoto <-- +{ +//yamamoto i2c_detach_client(client); + + kfree(client); + + return 0; +} + +static int i2ceeprom_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + + return -EINVAL; +} + +//yamamoto --> +static struct i2c_device_id i2ceeprom_idtable[] = { + { "i2ceeprom", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, i2ceeprom_idtable); +//yamamoto <-- + +static struct i2c_driver i2ceeprom_driver = { + .driver = { + .name = I2CEEPROM_MODULE_NAME, + }, +//yamamoto --> + .id_table = i2ceeprom_idtable, + .probe = i2ceeprom_probe, + .remove = __devexit_p(i2ceeprom_remove), +//yamamoto .id = I2C_DRIVERID_LARGEEEPROM, +//yamamoto .attach_adapter = i2ceeprom_probe, +//yamamoto .detach_client = i2ceeprom_detach, +//yamamoto <-- + .command = i2ceeprom_command +}; + + +static __init int i2ceeprom_init(void) +{ + int ret; + + info("I2C based EEPROM driver.\n"); + ret = i2c_add_driver(&i2ceeprom_driver); + if (ret) { + err("Register I2C driver failed, errno is %d\n", ret); + return ret; + } + return 0; +} + +static void __exit i2ceeprom_exit(void) +{ + i2c_del_driver(&i2ceeprom_driver); +} + +module_init(i2ceeprom_init); +module_exit(i2ceeprom_exit); diff -urN linux-2.6.32.56.org/drivers/i2c/chips/r2025x-rtc.c linux-2.6.32.56/drivers/i2c/chips/r2025x-rtc.c --- linux-2.6.32.56.org/drivers/i2c/chips/r2025x-rtc.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/drivers/i2c/chips/r2025x-rtc.c 2012-02-15 21:31:34.000000000 +0900 @@ -0,0 +1,506 @@ +/* + * linux/drivers/i2c/chips/r2025x-rtc.c + * + * I2C Real Time Clock Client Driver for Xicor R2025x RTC/Calendar + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * TODO: + * - implement alarm and periodic IRQ support. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG_R2025x +#define dbg(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args) +#else +#define dbg(fmt, args...) +#endif + +#define R2025x_MODULE_NAME "R2025x" +#define PFX R2025x_MODULE_NAME + +#define err(format, arg...) printk(KERN_ERR PFX ": " format , ## arg) +#define info(format, arg...) printk(KERN_INFO PFX ": " format , ## arg) +#define warn(format, arg...) printk(KERN_WARNING PFX ": " format , ## arg) +#define emerg(format, arg...) printk(KERN_EMERG PFX ": " format , ## arg) + + +#define R2025x_RTC_SR 0x3f +#define RTC_SR_RTCF (1) +#define RTC_SR_WEL (1<<1) +#define RTC_SR_RWEL (1<<2) + +#define R2025x_RTC_BASE 0x00 + +/* This is an image of the RTC registers starting at offset 0x30 */ +struct rtc_registers { + unsigned char secs; // 00 + unsigned char mins; // 01 + unsigned char hours; // 02 + unsigned char dayofweek;// 03 + unsigned char day; // 04 + unsigned char mon; // 05 + unsigned char year; // 06 + unsigned char adjust; // 07 + unsigned char almwmin; // 08 + unsigned char almwhours;// 09 + unsigned char almwdow; // 0a + unsigned char almdmin; // 0b + unsigned char almdhours;// 0c + unsigned char dummy; // 0d + unsigned char ctrl1; // 0e + unsigned char ctrl2; // 0f +}; + +#define RTC_ACCESS_WAIT 100 +#define DEVID_RTC 0x32 +#define SLAVE_READ 0x01 +#ifndef I2C_M_WR +#define I2C_M_WR 0x0 +#endif + +//yamamoto static struct i2c_driver r2025x_driver; + +static int r2025x_use_count = 0; + +static struct i2c_client *this_client = NULL; + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +static int r2025x_read (struct i2c_client *client, + u8 reg_offset, u8* buf, int len) +{ + u8* local_buf; + int ret; + struct i2c_msg random_addr_read; + + if (reg_offset > 15) + return -EINVAL; + if (reg_offset + len > 16) + return -EINVAL; + + if ((local_buf = (u8*)kmalloc(sizeof(struct rtc_registers) + 1, + GFP_KERNEL)) == NULL) { + err("buffer alloc failed\n"); + return -ENOMEM; + } + + random_addr_read.addr = client->addr; + random_addr_read.flags = client->flags| I2C_M_RD; + random_addr_read.len = 16; + random_addr_read.buf = local_buf; + + if ((ret = i2c_transfer(client->adapter, &random_addr_read, 1)) != 1) { + dbg("i2c_transfer failed %08x\n",ret); + ret = -ENXIO; + } + + local_buf[16] = local_buf[0]; + memcpy(buf, local_buf + 1 + reg_offset, len); + + kfree(local_buf); + udelay(RTC_ACCESS_WAIT); + return ret; +} + +static int r2025x_write (struct i2c_client *client, + u8 reg_offset, u8* buf, int len) +{ + int ret; + u8* local_buf; + struct i2c_msg page_write = { + client->addr, + client->flags , + len, + NULL + }; + + if (reg_offset > 15) + return -EINVAL; + if (reg_offset + len > 16) + return -EINVAL; + + if ((local_buf = (u8*)kmalloc(len + 1, + GFP_KERNEL)) == NULL) { + err("buffer alloc failed\n"); + return -ENOMEM; + } + + local_buf[0] = reg_offset; + memcpy(local_buf + 1, buf, len); + page_write.buf = local_buf; + + if ((ret = i2c_transfer(client->adapter, &page_write, 1)) != 1) { + ret = -ENXIO; + dbg("i2c_transfer failed\n"); + } + + kfree(local_buf); + udelay(RTC_ACCESS_WAIT); + return ret; +} + +static int +r2025x_get_time(struct i2c_client *client, struct rtc_time *tm) +{ + struct rtc_registers rtc; + int ret; + + /* read RTC registers */ + if ((ret = r2025x_read(client, R2025x_RTC_BASE, (u8*)&rtc, + sizeof(struct rtc_registers))) < 0) { + dbg("couldn't read RTC\n"); + return ret; + } + dbg("IN: year=%02x, mon=%02x, day=%02x, hour=%02x, " + "min=%02x, sec=%02x\n", + rtc.year, rtc.mon, rtc.day, rtc.hours, + rtc.mins, rtc.secs); + + tm->tm_year = ((rtc.year >>4 ) & 0xf) *10 + (rtc.year & 0x0f); + if (rtc.mon & 0x80) + tm->tm_year += 100; + tm->tm_mon = ((rtc.mon >>4 ) & 0x1) *10 + (rtc.mon & 0x0f); + tm->tm_mon--; /* tm_mon is 0 to 11 */ + tm->tm_mday = ((rtc.day >>4 ) & 0x3) *10 + (rtc.day & 0x0f); + tm->tm_hour = ((rtc.hours >>4 ) & 0x7) *10 + (rtc.hours & 0x0f); + if ((rtc.ctrl1 & 0x20) == 0) { + tm->tm_hour = ((rtc.hours >>4 ) & 0x1) *10 + (rtc.hours & 0x0f); + if (rtc.hours & 0x20) + tm->tm_hour += 12; + } else { + tm->tm_hour = ((rtc.hours >>4 ) & 0x3) *10 + (rtc.hours & 0x0f); + } + tm->tm_min = ((rtc.mins >>4 ) & 0x7) *10 + (rtc.mins & 0x0f); + tm->tm_sec = ((rtc.secs >>4 ) & 0x7) *10 + (rtc.secs & 0x0f); + + dbg("OUT: year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_sec); + + return 0; +} + +static int +r2025x_set_time(struct i2c_client *client, const struct rtc_time *tm) +{ + struct rtc_registers rtc; + int ret; + int tmpy; + + dbg("IN: year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_sec); + + tmpy = tm->tm_year % 100; + + rtc.year = (((tmpy / 10) << 4) | (tmpy % 10)); + rtc.mon = ((((tm->tm_mon + 1) / 10) << 4) | ((tm->tm_mon + 1) % 10)) & 0x3f; + if (tm->tm_year >= 100) + rtc.mon |= 0x80; + rtc.day = (((tm->tm_mday / 10) << 4) | (tm->tm_mday % 10)) & 0x3f; + rtc.dayofweek = 0; // ignore day of week + rtc.hours = (((tm->tm_hour / 10) << 4) | (tm->tm_hour % 10)) & 0x3f; + rtc.mins = (((tm->tm_min / 10) << 4) | (tm->tm_min % 10)) & 0x7f; + rtc.secs = (((tm->tm_sec / 10) << 4) | (tm->tm_sec % 10)) & 0x7f; + + dbg("OUT: year=%02x, mon=%02x, day=%02x, hour=%02x, " + "min=%02x, sec=%02x\n", + rtc.year, rtc.mon, rtc.day, rtc.hours, + rtc.mins, rtc.secs); + + /* write RTC registers */ + if ((ret = r2025x_write(client, R2025x_RTC_BASE, (u8*)&rtc, 8)) < 0) { + dbg("couldn't write RTC\n"); + return ret; + } + + return 0; +} + +//yamamoto --> +//yamamoto static int +//yamamoto r2025x_probe(struct i2c_adapter *adap) +static int r2025x_probe(struct i2c_client *client, const struct i2c_device_id *id) +//yamamoto <-- +{ + int ret; + struct rtc_registers rtc; + + if (this_client != NULL) + return -EBUSY; + + this_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (this_client == NULL) { + return -ENOMEM; + } + + memset(this_client, 0, sizeof(struct i2c_client)); + +//yamamoto --> + this_client = client; +//yamamoto <-- + +//yamamoto strcpy(this_client->name, R2025x_MODULE_NAME); +//yamamoto this_client->flags = 0; +//yamamoto this_client->addr = DEVID_RTC; +//yamamoto this_client->adapter = adap; +//yamamoto this_client->driver = &r2025x_driver; + + /* + * use r2025x_get_time() to probe for an R2025x on this bus. + */ + dbg("r2025x_probe Entry %08x\n",(u32)this_client); + if((ret = r2025x_read(this_client,R2025x_RTC_BASE, (u8 *)&rtc, + sizeof(struct rtc_registers)))< 0){ + dbg("r2025x_probe r2025x_read error\n"); + kfree(this_client); + this_client = NULL; + return ret; + } + +//yamamoto info("found R2025x on %s\n", adap->name); + +//yamamoto --> +//yamamoto /* attach it. */ +//yamamoto dbg("r2025x_probe i2c_attach_client call\n"); +//yamamoto ret = i2c_attach_client(this_client); +//yamamoto dbg("r2025x_probe i2c_attach_client call ret=%d\n",ret); +//yamamoto <-- + return ret; +} + +//yamamoto --> +//yamamoto static int +//yamamoto r2025x_detach(struct i2c_client *client) +static int r2025x_remove(struct i2c_client *client) +//yamamoto <-- +{ +//yamamoto i2c_detach_client(client); + + if (this_client != NULL) { + kfree(this_client); + this_client = NULL; + } + + return 0; +} + +int rtc_open(struct inode *minode, struct file *mfile) +{ + /*if(MOD_IN_USE)*/ + if(r2025x_use_count > 0) { + return -EBUSY; + } +// MOD_INC_USE_COUNT; + ++r2025x_use_count; + return 0; +} + +int rtc_release(struct inode *minode, struct file *mfile) +{ +// MOD_DEC_USE_COUNT; + --r2025x_use_count; + return 0; +} + +static loff_t rtc_llseek(struct file *mfile, loff_t offset, int origint) +{ + return -ESPIPE; +} + +static int +r2025x_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + return -EINVAL; +} + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_time rtc_tm; + int ret; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + if ((ret = r2025x_get_time(this_client, &rtc_tm)) < 0) + return ret; + return copy_to_user((void *)arg, &rtc_tm, sizeof(rtc_tm)) ? + -EFAULT : 0; + case RTC_SET_TIME: /* Set the RTC */ + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, + (struct rtc_time *) arg, + sizeof(struct rtc_time))) + return -EFAULT; + + return r2025x_set_time(this_client, &rtc_tm); + default: + return -EINVAL; + } +} + +//yamamoto --> +static struct i2c_device_id r2025x_idtable[] = { + { "r2025x", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, r2025x_idtable); +//yamamoto <-- + +static struct i2c_driver r2025x_driver = { + .driver = { + .name = R2025x_MODULE_NAME, + }, +//yamamoto --> + .id_table = r2025x_idtable, + .probe = r2025x_probe, + .remove = __devexit_p(r2025x_remove), +//yamamoto .id = I2C_DRIVERID_R2025x, +//yamamoto .attach_adapter = r2025x_probe, +//yamamoto .detach_client = r2025x_detach, +//yamamoto <-- + .command = r2025x_command +}; + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + llseek: rtc_llseek, + ioctl: rtc_ioctl, + open: rtc_open, + release: rtc_release, +}; + +static struct miscdevice r2025xrtc_miscdev = { + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static __init int r2025x_init(void) +{ + int ret; + + info("I2C based RTC driver.\n"); + ret = i2c_add_driver(&r2025x_driver); + dbg("r2025x_init i2c_add_driver call ret=%d\n",ret); + if (ret) { + err("Register I2C driver failed, errno is %d\n", ret); + return ret; + } + dbg("r2025x_init misc_register call\n"); + ret = misc_register(&r2025xrtc_miscdev); + dbg("r2025x_init misc_register call ret=%d\n",ret); + if (ret) { + err("Register misc driver failed, errno is %d\n", ret); + i2c_del_driver(&r2025x_driver); + return ret; + } + + create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL); + dbg("r2025x_init Success\n"); + return 0; +} + +static void __exit r2025x_exit(void) +{ + remove_proc_entry("driver/rtc", NULL); + misc_deregister(&r2025xrtc_miscdev); + i2c_del_driver(&r2025x_driver); +} + + +module_init(r2025x_init); +module_exit(r2025x_exit); + +/* + * Info exported via "/proc/driver/rtc". + */ + +static int rtc_proc_output(char *buf) +{ + char *p; + struct rtc_time tm; + int ret; + + if ((ret = r2025x_get_time(this_client, &tm)) < 0) + return ret; + + p = buf; + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, + tm.tm_mday); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_proc_output(page); + if (len <= off + count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + return len; +} + +MODULE_AUTHOR("Steve Longerbeam"); +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.32.56.org/drivers/mtd/maps/alchemy-flash.c linux-2.6.32.56/drivers/mtd/maps/alchemy-flash.c --- linux-2.6.32.56.org/drivers/mtd/maps/alchemy-flash.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/mtd/maps/alchemy-flash.c 2012-02-15 10:20:12.000000000 +0900 @@ -69,6 +69,12 @@ #define BOARD_FLASH_WIDTH 4 /* 32-bits */ #endif +#ifdef CONFIG_MIPS_OMS400 +#define BOARD_MAP_NAME "OpenMicroServer Flash" +#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */ +#define BOARD_FLASH_WIDTH 2 /* 16-bits */ +#endif + #ifdef CONFIG_MIPS_DB1200 #define BOARD_MAP_NAME "Db1200 Flash" #define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ @@ -94,18 +100,45 @@ static struct mtd_partition alchemy_partitions[] = { { +#ifdef CONFIG_MIPS_OMS400 + .name = "Firmware", +#else .name = "User FS", +#endif .size = BOARD_FLASH_SIZE - 0x00400000, .offset = 0x0000000 },{ .name = "YAMON", +#ifdef CONFIG_MIPS_OMS400 + .size = 0x0180000, +#else .size = 0x0100000, +#endif .offset = MTDPART_OFS_APPEND, .mask_flags = MTD_WRITEABLE },{ +#ifdef CONFIG_MIPS_OMS400 + .name = "User Area", + .size = 0x00200000, + .offset = MTDPART_OFS_APPEND + },{ + .name = "flashcfg save area", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND + },{ + .name = "YAMON Params", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND + },{ + .name = "Entire Flash ROM", + .size = BOARD_FLASH_SIZE, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE +#else .name = "raw kernel", .size = (0x300000 - 0x40000), /* last 256KB is yamon env */ .offset = MTDPART_OFS_APPEND, +#endif } }; diff -urN linux-2.6.32.56.org/drivers/net/Kconfig linux-2.6.32.56/drivers/net/Kconfig --- linux-2.6.32.56.org/drivers/net/Kconfig 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/net/Kconfig 2012-02-15 10:28:12.000000000 +0900 @@ -1590,6 +1590,10 @@ To compile this driver as a module, choose M here: the module will be called 8139too. This is recommended. +config 8139TOO_NAPI + bool "Use Rx Polling (NAPI)" + depends on 8139TOO + config 8139TOO_PIO bool "Use PIO instead of MMIO" default y @@ -2118,6 +2122,29 @@ To compile this driver as a module, choose M here. The module will be called igbvf. +choice + prompt "E1000 Rx buffer size" + depends on E1000 && MIPS_OMS400 + default E1000_RX_BUFSIZE_48K + help + Set E1000 rx buffter size. + +config E1000_RX_BUFSIZE_48K + bool "48K" + +config E1000_RX_BUFSIZE_40K + bool "40K" + +config E1000_RX_BUFSIZE_32K + bool "32K" + +endchoice + +config E1000_NOCOPY_SMALL_SKB + bool "Do not copy skb when length < 256" + depends on E1000 && MIPS_OMS400 + default n + source "drivers/net/ixp2000/Kconfig" config MYRI_SBUS diff -urN linux-2.6.32.56.org/drivers/net/Makefile linux-2.6.32.56/drivers/net/Makefile --- linux-2.6.32.56.org/drivers/net/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/net/Makefile 2012-02-15 10:34:09.000000000 +0900 @@ -8,6 +8,7 @@ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o +obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o obj-$(CONFIG_E1000) += e1000/ obj-$(CONFIG_E1000E) += e1000e/ obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/ @@ -216,7 +217,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_KORINA) += korina.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o -obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o +#obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o obj-$(CONFIG_DECLANCE) += declance.o diff -urN linux-2.6.32.56.org/drivers/net/e1000/e1000_main.c linux-2.6.32.56/drivers/net/e1000/e1000_main.c --- linux-2.6.32.56.org/drivers/net/e1000/e1000_main.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/net/e1000/e1000_main.c 2012-02-15 10:48:18.000000000 +0900 @@ -542,8 +542,15 @@ case e1000_82540: case e1000_82541: case e1000_82541_rev_2: +#if defined(CONFIG_E1000_RX_BUFSIZE_32K) + pba = E1000_PBA_32K; +#elif defined(CONFIG_E1000_RX_BUFSIZE_40K) + legacy_pba_adjust = true; + pba = E1000_PBA_40K; +#else legacy_pba_adjust = true; pba = E1000_PBA_48K; +#endif break; case e1000_82545: case e1000_82545_rev_3: @@ -3878,6 +3885,7 @@ /* code added for copybreak, this should improve * performance for small packets with large amounts * of reassembly being done in the stack */ +#ifndef CONFIG_E1000_NOCOPY_SMALL_SKB if (length < copybreak) { struct sk_buff *new_skb = netdev_alloc_skb(netdev, length + NET_IP_ALIGN); @@ -3896,6 +3904,7 @@ /* else just continue with the old one */ } /* end copybreak code */ +#endif skb_put(skb, length); /* Receive Checksum Offload */ diff -urN linux-2.6.32.56.org/drivers/net/phy/lxt.c linux-2.6.32.56/drivers/net/phy/lxt.c --- linux-2.6.32.56.org/drivers/net/phy/lxt.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/net/phy/lxt.c 2012-02-15 10:56:03.000000000 +0900 @@ -97,6 +97,16 @@ return err; } +#ifdef CONFIG_MIPS_OMS400 +#define MII_LXT971A_CFG 16 /* PHY Configuration Register */ +static int lxt971_config_init(struct phy_device *phydev) +{ + int err; + + err = phy_write(phydev, MII_LXT971A_CFG, 0x0180); + return err; +} +#endif static int lxt971_ack_interrupt(struct phy_device *phydev) { @@ -140,6 +150,9 @@ .phy_id_mask = 0xfffffff0, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, +#ifdef CONFIG_MIPS_OMS400 + .config_init = lxt971_config_init, +#endif .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = lxt971_ack_interrupt, diff -urN linux-2.6.32.56.org/drivers/pcmcia/Makefile linux-2.6.32.56/drivers/pcmcia/Makefile --- linux-2.6.32.56.org/drivers/pcmcia/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/pcmcia/Makefile 2012-02-15 11:00:42.000000000 +0900 @@ -48,6 +48,7 @@ au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o +au1x00_ss-$(CONFIG_MIPS_OMS400) += au1000_db1x00.o au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o sa1111_cs-y += sa1111_generic.o diff -urN linux-2.6.32.56.org/drivers/pcmcia/au1000_db1x00.c linux-2.6.32.56/drivers/pcmcia/au1000_db1x00.c --- linux-2.6.32.56.org/drivers/pcmcia/au1000_db1x00.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/pcmcia/au1000_db1x00.c 2012-02-15 11:11:36.000000000 +0900 @@ -47,8 +47,10 @@ #include #else #include +#ifndef CONFIG_MIPS_OMS400 static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #endif +#endif #include "au1000_generic.h" @@ -58,12 +60,18 @@ #define debug(x,args...) #endif - +#ifdef CONFIG_MIPS_OMS400 +struct au1000_pcmcia_socket au1000_pcmcia_socket[2]; +#else struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS]; +#endif extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int); static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt) { +#ifdef CONFIG_MIPS_OMS400 + skt->irq = AU1000_GPIO_3; +#else #ifdef CONFIG_MIPS_DB1550 skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3; #elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200) @@ -71,12 +79,15 @@ #else skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2; #endif +#endif return 0; } static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt) { +#ifndef CONFIG_MIPS_OMS400 bcsr->pcmcia = 0; /* turn off power */ +#endif au_sync_delay(2); } @@ -93,20 +104,30 @@ switch (skt->nr) { case 0: +#ifdef CONFIG_MIPS_OMS400 + vs = 2; + inserted = !(au_readl(SYS_PINSTATERD) & (1 << 5)); +#else vs = bcsr->status & 0x3; #if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200) inserted = BOARD_CARD_INSERTED(0); #else inserted = !(bcsr->status & (1<<4)); #endif +#endif break; case 1: +#ifdef CONFIG_MIPS_OMS400 + vs = 0; + inserted = 0; +#else vs = (bcsr->status & 0xC)>>2; #if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200) inserted = BOARD_CARD_INSERTED(1); #else inserted = !(bcsr->status & (1<<5)); #endif +#endif break; default:/* should never happen */ return; @@ -132,6 +153,7 @@ state->detect = 1; state->ready = 1; } +#ifndef CONFIG_MIPS_OMS400 else { /* if the card was previously inserted and then ejected, * we should turn off power to it @@ -151,6 +173,7 @@ au_sync_delay(10); } } +#endif state->bvd1=1; state->bvd2=1; @@ -160,6 +183,7 @@ static int db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state) { +#ifndef CONFIG_MIPS_OMS400 u16 pwr; int sock = skt->nr; @@ -261,6 +285,7 @@ au_sync_delay(100); } } +#endif return 0; } @@ -298,8 +323,12 @@ int au1x_board_init(struct device *dev) { int ret = -ENODEV; +#ifdef CONFIG_MIPS_OMS400 + ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 1); +#else bcsr->pcmcia = 0; /* turn off power, if it's not already off */ au_sync_delay(2); ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2); +#endif return ret; } diff -urN linux-2.6.32.56.org/drivers/pcmcia/au1000_generic.c linux-2.6.32.56/drivers/pcmcia/au1000_generic.c --- linux-2.6.32.56.org/drivers/pcmcia/au1000_generic.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/pcmcia/au1000_generic.c 2012-02-15 11:25:19.000000000 +0900 @@ -408,6 +408,7 @@ skt->phys_attr = AU1X_SOCK0_PSEUDO_PHYS_ATTR; skt->phys_mem = AU1X_SOCK0_PSEUDO_PHYS_MEM; } +#ifndef CONFIG_MIPS_OMS400 #ifndef CONFIG_MIPS_XXS1500 else { skt->virt_io = (void *) @@ -417,6 +418,7 @@ skt->phys_mem = AU1X_SOCK1_PSEUDO_PHYS_MEM; } #endif +#endif pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io; ret = ops->hw_init(skt); @@ -425,6 +427,7 @@ skt->socket.map_size = MAP_SIZE; skt->socket.pci_irq = skt->irq; skt->socket.io_offset = (unsigned long)skt->virt_io; + skt->socket.resource_ops = &pccard_static_ops; skt->status = au1x00_pcmcia_skt_state(skt); diff -urN linux-2.6.32.56.org/drivers/pcmcia/ds.c linux-2.6.32.56/drivers/pcmcia/ds.c --- linux-2.6.32.56.org/drivers/pcmcia/ds.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/pcmcia/ds.c 2012-02-15 11:30:27.000000000 +0900 @@ -955,8 +955,10 @@ */ ds_dev_dbg(0, &dev->dev, "skipping FUNC_ID match until userspace interaction\n"); +#ifndef CONFIG_MIPS_OMS400 if (!dev->allow_func_id_match) return 0; +#endif } if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { diff -urN linux-2.6.32.56.org/drivers/serial/8250.c linux-2.6.32.56/drivers/serial/8250.c --- linux-2.6.32.56.org/drivers/serial/8250.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/serial/8250.c 2012-02-15 11:32:53.000000000 +0900 @@ -91,7 +91,11 @@ * machine types want others as well - they're free * to redefine this in their header file. */ +#if defined(CONFIG_MIPS_OMS400) +#define is_real_interrupt(irq) ((irq) < 0x100) +#else #define is_real_interrupt(irq) ((irq) != 0) +#endif #ifdef CONFIG_SERIAL_8250_DETECT_IRQ #define CONFIG_SERIAL_DETECT_IRQ 1 diff -urN linux-2.6.32.56.org/drivers/usb/host/ehci.h linux-2.6.32.56/drivers/usb/host/ehci.h --- linux-2.6.32.56.org/drivers/usb/host/ehci.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/usb/host/ehci.h 2012-02-15 11:44:20.000000000 +0900 @@ -342,7 +342,13 @@ * memory that is cache-inhibited (i.e. being used for DMA). * Spinlocks are used to protect all QH fields. */ +#ifdef CONFIG_MIPS_OMS400 + u8 __isolete_cache_1[1024]; u32 refcount; + u8 __isolate_cashe_2[1024]; +#else + u32 refcount; +#endif unsigned stamp; u8 needs_rescan; /* Dequeue during giveback */ diff -urN linux-2.6.32.56.org/drivers/usb/host/ohci-hcd.c linux-2.6.32.56/drivers/usb/host/ohci-hcd.c --- linux-2.6.32.56.org/drivers/usb/host/ohci-hcd.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/drivers/usb/host/ohci-hcd.c 2012-02-15 11:50:55.000000000 +0900 @@ -1033,10 +1033,12 @@ #define PLATFORM_DRIVER ohci_hcd_ep93xx_driver #endif +#ifndef CONFIG_MIPS_OMS400 #ifdef CONFIG_SOC_AU1X00 #include "ohci-au1xxx.c" #define PLATFORM_DRIVER ohci_hcd_au1xxx_driver #endif +#endif #ifdef CONFIG_PNX8550 #include "ohci-pnx8550.c" diff -urN linux-2.6.32.56.org/include/asm-generic/bug.h linux-2.6.32.56/include/asm-generic/bug.h --- linux-2.6.32.56.org/include/asm-generic/bug.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/include/asm-generic/bug.h 2012-02-15 22:01:13.000000000 +0900 @@ -126,6 +126,13 @@ }) #endif +#ifndef WARN_RATELIMIT +#define WARN_RATELIMIT(condition, format...) ({ \ + int __ret_warn_on = !!(condition); \ + unlikely(__ret_warn_on); \ +}) +#endif + #endif #define WARN_ON_ONCE(condition) ({ \ diff -urN linux-2.6.32.56.org/include/asm-generic/int-ll64.h linux-2.6.32.56/include/asm-generic/int-ll64.h --- linux-2.6.32.56.org/include/asm-generic/int-ll64.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/include/asm-generic/int-ll64.h 2012-02-15 11:57:43.000000000 +0900 @@ -25,13 +25,13 @@ typedef __signed__ int __s32; typedef unsigned int __u32; -#ifdef __GNUC__ +//#ifdef __GNUC__ __extension__ typedef __signed__ long long __s64; __extension__ typedef unsigned long long __u64; -#else -typedef __signed__ long long __s64; -typedef unsigned long long __u64; -#endif +//#else +//typedef __signed__ long long __s64; +//typedef unsigned long long __u64; +//#endif #endif /* __ASSEMBLY__ */ diff -urN linux-2.6.32.56.org/include/linux/miscdevice.h linux-2.6.32.56/include/linux/miscdevice.h --- linux-2.6.32.56.org/include/linux/miscdevice.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/include/linux/miscdevice.h 2012-02-15 14:21:15.000000000 +0900 @@ -1,5 +1,11 @@ #ifndef _LINUX_MISCDEVICE_H #define _LINUX_MISCDEVICE_H + +/* + PlatHome + - Added PUSHSW_MINOR, SEGLED_MINOR for OpenBlockS +*/ + #include #include @@ -22,6 +28,10 @@ #define SGI_MMTIMER 153 #define STORE_QUEUE_MINOR 155 #define I2O_MINOR 166 +#define PUSHSW_MINOR 170 +#define SEGLED_MINOR 171 +#define OMS400TEMP_MINOR 172 +#define OMS400DIO_MINOR 173 #define MICROCODE_MINOR 184 #define TUN_MINOR 200 #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ diff -urN linux-2.6.32.56.org/include/linux/netfilter.h linux-2.6.32.56/include/linux/netfilter.h --- linux-2.6.32.56.org/include/linux/netfilter.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/include/linux/netfilter.h 2012-02-15 14:26:20.000000000 +0900 @@ -13,6 +13,7 @@ #endif #include #include +#include /* Responses from hook functions. */ #define NF_DROP 0 diff -urN linux-2.6.32.56.org/include/linux/types.h linux-2.6.32.56/include/linux/types.h --- linux-2.6.32.56.org/include/linux/types.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/include/linux/types.h 2012-02-15 14:35:25.000000000 +0900 @@ -179,7 +179,7 @@ typedef unsigned __bitwise__ gfp_t; typedef unsigned __bitwise__ fmode_t; -#ifdef CONFIG_PHYS_ADDR_T_64BIT +#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR) typedef u64 phys_addr_t; #else typedef u32 phys_addr_t; diff -urN linux-2.6.32.56.org/include/pcmcia/ds.h linux-2.6.32.56/include/pcmcia/ds.h --- linux-2.6.32.56.org/include/pcmcia/ds.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/include/pcmcia/ds.h 2012-02-15 21:51:06.000000000 +0900 @@ -244,10 +244,12 @@ #if defined(CONFIG_PCMCIA_IOCTL) || !defined(__KERNEL__) -#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \ +#if defined(__arm__) || defined(__avr32__) || \ defined(__bfin__) /* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */ typedef u_int ioaddr_t; +#elif defined(__mips__) +typedef unsigned long long ioaddr_t; #else typedef u_short ioaddr_t; #endif @@ -434,6 +436,9 @@ #define INFO_CARD_SHARE 0x10 #define INFO_CARD_EXCL 0x20 +#ifdef CONFIG_MIPS_OMS400 +int pcmcia_bind_request(bind_info_t *bind_info); +#endif #endif /* !defined(__KERNEL__) || defined(CONFIG_PCMCIA_IOCTL) */ diff -urN linux-2.6.32.56.org/init/do_mounts.c linux-2.6.32.56/init/do_mounts.c --- linux-2.6.32.56.org/init/do_mounts.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/init/do_mounts.c 2012-02-15 14:52:12.000000000 +0900 @@ -57,6 +57,17 @@ __setup("ro", readonly); __setup("rw", readwrite); +#if defined(CONFIG_MIPS_OMS400) +int __initdata no_flashcfg; + +static int __init exec_flashcfg(char * str) +{ + no_flashcfg = simple_strtoul(str,NULL,0); + return 1; +} +__setup("noflashcfg=", exec_flashcfg); +#endif + /* * Convert a name into device number. We accept the following variants: * @@ -366,6 +377,10 @@ { int is_floppy; +#if defined(CONFIG_MIPS_OMS400) + int real_root_mountflags = root_mountflags; +#endif + if (root_delay) { printk(KERN_INFO "Waiting %dsec before mounting root device...\n", root_delay); @@ -413,9 +428,33 @@ if (is_floppy && rd_doload && rd_load_disk(0)) ROOT_DEV = Root_RAM0; +#if defined(CONFIG_MIPS_OMS400) + /* write able root mount if load user configuration from flash necessary. */ + if ((no_flashcfg == 0) && mount_initrd) { + root_mountflags &= ~MS_RDONLY; + } +#endif + mount_root(); out: devtmpfs_mount("dev"); sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); +#if defined(CONFIG_MIPS_OMS400) + if ((no_flashcfg == 0) && mount_initrd) { + root_mountflags = real_root_mountflags; + printk("[prepare_namespace] Executing flashcfg...\n"); + if ((MAJOR(ROOT_DEV) == RAMDISK_MAJOR) && (MINOR(ROOT_DEV) == 0)) { + int pid,i; + pid = kernel_thread(do_restore, "/usr/sbin/flashcfg", SIGCHLD); + if (pid > 0) { + while (pid != sys_wait4(-1, &i, 0, NULL)) + yield(); + } + else + printk("[prepare_namespace] Error starting restore thread!\n"); + } + printk("[prepare_namespace] Finished executing flashcfg\n"); + } +#endif } diff -urN linux-2.6.32.56.org/init/do_mounts.h linux-2.6.32.56/init/do_mounts.h --- linux-2.6.32.56.org/init/do_mounts.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/init/do_mounts.h 2012-02-15 14:53:58.000000000 +0900 @@ -55,6 +55,8 @@ #endif +extern int __initdata mount_initrd; + #ifdef CONFIG_BLK_DEV_INITRD int __init initrd_load(void); @@ -74,3 +76,7 @@ static inline void md_run_setup(void) {} #endif + +#if defined(CONFIG_MIPS_OMS400) +int __init do_restore(void *shell); +#endif diff -urN linux-2.6.32.56.org/init/do_mounts_initrd.c linux-2.6.32.56/init/do_mounts_initrd.c --- linux-2.6.32.56.org/init/do_mounts_initrd.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/init/do_mounts_initrd.c 2012-02-15 14:58:30.000000000 +0900 @@ -10,11 +10,20 @@ #include "do_mounts.h" +/* + ozawa CONFIG_OBSS + PlatHome + - Added do_restore() + - write able root mount if load user configuration + in prepare_namespace() + - Added for CONFIG_MIPS_OMS400 +*/ + unsigned long initrd_start, initrd_end; int initrd_below_start_ok; unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ static int __initdata old_fd, root_fd; -static int __initdata mount_initrd = 1; +int __initdata mount_initrd = 1; static int __init no_initrd(char *str) { @@ -127,3 +136,23 @@ sys_unlink("/initrd.image"); return 0; } + +#if defined(CONFIG_MIPS_OMS400) +int __init do_restore(void *shell) +{ + static char *argv[] = { "flashcfg", + "-x", + NULL, }; + extern char *envp_init[]; + + sys_close(old_fd);sys_close(root_fd); + sys_close(0);sys_close(1);sys_close(2); + sys_setsid(); + (void) sys_open("/dev/console",O_RDWR,0); + (void) sys_dup(0); + (void) sys_dup(0); + kernel_execve(shell, argv, envp_init); + printk("[do_restore] Error starting restore thread!\n"); + return (-1); +} +#endif diff -urN linux-2.6.32.56.org/init/do_mounts_rd.c linux-2.6.32.56/init/do_mounts_rd.c --- linux-2.6.32.56.org/init/do_mounts_rd.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/init/do_mounts_rd.c 2012-02-15 15:02:36.000000000 +0900 @@ -1,3 +1,11 @@ +/* + ozawa CONFIG_OBSS + PlatHome + - Added do_restore() + - write able root mount if load user configuration + in prepare_namespace() + - Added for CONFIG_MIPS_OMS400 +*/ #include #include @@ -158,7 +166,11 @@ { int res = 0; int in_fd, out_fd; +#if defined(CONFIG_MIPS_OMS400) + long rd_blocks, devblocks; +#else unsigned long rd_blocks, devblocks; +#endif int nblocks, i, disk; char *buf = NULL; unsigned short rotate = 0; diff -urN linux-2.6.32.56.org/init/main.c linux-2.6.32.56/init/main.c --- linux-2.6.32.56.org/init/main.c 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/init/main.c 2012-02-15 15:15:02.000000000 +0900 @@ -7,6 +7,14 @@ * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96 * Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96 * Simplified starting of init: Michael A. Griffith + * + * Century + * - Added LED display + * - Added recovery mode handling + * 2001-12-25 ozawa CONFIG_OBSS + * PlatHome + * - Added for OpenBlockS 266 + * */ #include @@ -101,6 +109,14 @@ enum system_states system_state __read_mostly; EXPORT_SYMBOL(system_state); +#if defined(CONFIG_MIPS_OMS400) && defined(CONFIG_OMS400_LED) +#define STATUS_LED_OUT 1 +#endif + +#if defined(STATUS_LED_OUT) +extern int obsled_out(int); +#endif + /* * Boot command-line arguments */ @@ -522,6 +538,9 @@ char * command_line; extern struct kernel_param __start___param[], __stop___param[]; +#if defined(STATUS_LED_OUT) + obsled_out(1); +#endif smp_setup_processor_id(); /* @@ -550,6 +569,9 @@ tick_init(); boot_cpu_init(); page_address_init(); +#if defined(STATUS_LED_OUT) + obsled_out(2); +#endif printk(KERN_NOTICE "%s", linux_banner); setup_arch(&command_line); mm_init_owner(&init_mm, &init_task); @@ -834,6 +856,9 @@ * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ +#if defined(STATUS_LED_OUT) + obsled_out(6); +#endif if (execute_command) { run_init_process(execute_command); printk(KERN_WARNING "Failed to execute %s. Attempting " @@ -855,6 +880,9 @@ wait_for_completion(&kthreadd_done); lock_kernel(); +#if defined(STATUS_LED_OUT) + obsled_out(3); +#endif /* * init can allocate pages on any node */ @@ -883,8 +911,15 @@ smp_init(); sched_init_smp(); +#if defined(STATUS_LED_OUT) + obsled_out(4); +#endif do_basic_setup(); +#if defined(STATUS_LED_OUT) + obsled_out(5); +#endif + /* * check if there is an early userspace init. If yes, let it do all * the work diff -urN linux-2.6.32.56.org/kernel/Kconfig.hz linux-2.6.32.56/kernel/Kconfig.hz --- linux-2.6.32.56.org/kernel/Kconfig.hz 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/kernel/Kconfig.hz 2012-02-15 15:18:38.000000000 +0900 @@ -23,6 +23,12 @@ with lots of processors that may show reduced performance if too many timer interrupts are occurring. + config HZ_125 + bool "125 HZ" + + config HZ_200 + bool "200 HZ" + config HZ_250 bool "250 HZ" help @@ -39,6 +45,9 @@ on SMP and NUMA systems and exactly dividing by both PAL and NTSC frame rates for video and multimedia work. + config HZ_500 + bool "500 HZ" + config HZ_1000 bool "1000 HZ" help @@ -50,8 +59,11 @@ config HZ int default 100 if HZ_100 + default 125 if HZ_125 + default 200 if HZ_200 default 250 if HZ_250 default 300 if HZ_300 + default 500 if HZ_500 default 1000 if HZ_1000 config SCHED_HRTICK diff -urN linux-2.6.32.56.org/scripts/Makefile.modinst linux-2.6.32.56/scripts/Makefile.modinst --- linux-2.6.32.56.org/scripts/Makefile.modinst 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/scripts/Makefile.modinst 2012-02-15 15:20:09.000000000 +0900 @@ -17,7 +17,7 @@ @: quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; gzip -9 $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff -urN linux-2.6.32.56.org/sound/usb/usbquirks.h linux-2.6.32.56/sound/usb/usbquirks.h --- linux-2.6.32.56.org/sound/usb/usbquirks.h 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/sound/usb/usbquirks.h 2012-02-15 15:22:28.000000000 +0900 @@ -1916,6 +1916,17 @@ } }, +{ + /* Creative Sound Blaster Degital Music LX */ + USB_DEVICE(0x041e, 0x3015), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Creative Labs", + .product_name = "Sound Blaster Music LX", + .ifnum = QUIRK_NO_INTERFACE + } + +}, + /* Emagic devices */ { USB_DEVICE(0x086a, 0x0001), diff -urN linux-2.6.32.56.org/usr/Makefile linux-2.6.32.56/usr/Makefile --- linux-2.6.32.56.org/usr/Makefile 2012-02-12 10:48:12.000000000 +0900 +++ linux-2.6.32.56/usr/Makefile 2012-02-15 15:24:12.000000000 +0900 @@ -59,3 +59,13 @@ $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d $(call if_changed,initfs) +ifdef CONFIG_MIPS_OMS400 + +obj-y += initrd_data.o + +$(obj)/initrd_data.o: $(obj)/ramdisk.image.gz FORCE + +$(obj)/ramdisk.image.gz: + touch $(obj)/ramdisk.image.gz + +endif diff -urN linux-2.6.32.56.org/usr/initrd_data.S linux-2.6.32.56/usr/initrd_data.S --- linux-2.6.32.56.org/usr/initrd_data.S 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.32.56/usr/initrd_data.S 2012-02-14 12:01:40.000000000 +0900 @@ -0,0 +1,7 @@ +.section .initrd_data,"a" +.global Initrd_Data +_initrdstart: +.incbin "usr/ramdisk.image.gz" +_initrdend: +Initrd_Data: +.word 0x494e5244 , _initrdstart , _initrdend