On Tue, Aug 21, 2007 at 10:34:16PM +0200, brm wrote: Patch queued for 2.6.24 but here a few more comments. > drivers/mtd/maps/Kconfig | 6 + > drivers/mtd/maps/Makefile | 1 + > drivers/mtd/maps/lasat.c | 103 +++++++ I've stripped these from the patch. Please submit the MTD bits to the MTD maintainers: MEMORY TECHNOLOGY DEVICES (MTD) P: David Woodhouse M: dwmw2@xxxxxxxxxxxxx W: http://www.linux-mtd.infradead.org/ L: linux-mtd@xxxxxxxxxxxxxxxxxxx T: git git://git.infradead.org/mtd-2.6.git S: Maintained > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig > index 516b18d..793590b 100644 > --- a/arch/mips/Kconfig > +++ b/arch/mips/Kconfig > @@ -107,6 +107,20 @@ config MACH_JAZZ > Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and > Olivetti M700-10 workstations. > > +config LASAT > + bool "LASAT Networks platforms" > + select DMA_NONCOHERENT > + select SYS_HAS_EARLY_PRINTK > + select HW_HAS_PCI > + select PCI_GT64XXX_PCI0 > + select MIPS_NILE4 > + select R5000_CPU_SCACHE > + select SYS_HAS_CPU_R5000 > + select SYS_SUPPORTS_32BIT_KERNEL > + select SYS_SUPPORTS_64BIT_KERNEL if BROKEN > + select SYS_SUPPORTS_LITTLE_ENDIAN > + select GENERIC_HARDIRQS_NO__DO_IRQ > + > config LEMOTE_FULONG > bool "Lemote Fulong mini-PC" > select ARCH_SPARSEMEM_ENABLE > @@ -598,6 +612,7 @@ endchoice > > source "arch/mips/au1000/Kconfig" > source "arch/mips/jazz/Kconfig" > +source "arch/mips/lasat/Kconfig" > source "arch/mips/pmc-sierra/Kconfig" > source "arch/mips/sgi-ip27/Kconfig" > source "arch/mips/sibyte/Kconfig" > @@ -713,6 +728,9 @@ config MIPS_BONITO64 > config MIPS_MSC > bool > > +config MIPS_NILE4 > + bool > + > config MIPS_DISABLE_OBSOLETE_IDE > bool > > diff --git a/arch/mips/Makefile b/arch/mips/Makefile > index 32c1c8f..34c39fc 100644 > --- a/arch/mips/Makefile > +++ b/arch/mips/Makefile > @@ -367,6 +367,13 @@ cflags-$(CONFIG_BASLER_EXCITE) += -Iinclude/asm-mips/mach-excite > load-$(CONFIG_BASLER_EXCITE) += 0x80100000 > > # > +# LASAT platforms > +# > +core-$(CONFIG_LASAT) += arch/mips/lasat/ > +cflags-$(CONFIG_LASAT) += -Iinclude/asm-mips/mach-lasat > +load-$(CONFIG_LASAT) += 0xffffffff80000000 > + > +# > # Common VR41xx > # > core-$(CONFIG_MACH_VR41XX) += arch/mips/vr41xx/common/ > @@ -615,6 +622,11 @@ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ > > drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ > > +ifdef CONFIG_LASAT > +rom.bin rom.sw: vmlinux > + $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@ > +endif > + > # > # Some machines like the Indy need 32-bit ELF binaries for booting purposes. > # Other need ECOFF, so we build a 32-bit ELF binary for them which we then > @@ -658,6 +670,7 @@ endif > > archclean: > @$(MAKE) $(clean)=arch/mips/boot > + @$(MAKE) $(clean)=arch/mips/lasat > > define archhelp > echo ' vmlinux.ecoff - ECOFF boot image' > diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig > new file mode 100644 > index 0000000..1d2ee8a > --- /dev/null > +++ b/arch/mips/lasat/Kconfig > @@ -0,0 +1,15 @@ > +config PICVUE > + tristate "PICVUE LCD display driver" > + depends on LASAT > + > +config PICVUE_PROC > + tristate "PICVUE LCD display driver /proc interface" > + depends on PICVUE > + > +config DS1603 > + bool "DS1603 RTC driver" > + depends on LASAT > + > +config LASAT_SYSCTL > + bool "LASAT sysctl interface" > + depends on LASAT > diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile > new file mode 100644 > index 0000000..9cc4e4d > --- /dev/null > +++ b/arch/mips/lasat/Makefile > @@ -0,0 +1,14 @@ > +# > +# Makefile for the LASAT specific kernel interface routines under Linux. > +# > + > +obj-y += reset.o setup.o prom.o lasat_board.o \ > + at93c.o interrupt.o serial.o > + > +obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o > +obj-$(CONFIG_DS1603) += ds1603.o > +obj-$(CONFIG_PICVUE) += picvue.o > +obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o > + > +clean: > + make -C image clean > diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c > new file mode 100644 > index 0000000..ca26e55 > --- /dev/null > +++ b/arch/mips/lasat/at93c.c > @@ -0,0 +1,148 @@ > +/* > + * Atmel AT93C46 serial eeprom driver > + * > + * Brian Murphy <brian.murphy@xxxxxxxxx> > + * > + */ > +#include <linux/kernel.h> > +#include <linux/delay.h> > +#include <asm/lasat/lasat.h> > +#include <linux/module.h> > +#include <linux/init.h> > + > +#include "at93c.h" > + > +#define AT93C_ADDR_SHIFT 7 > +#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1) > +#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT) > +#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT) > +#define AT93C_WENCMD 0x260 > +#define AT93C_WDSCMD 0x200 > + > +struct at93c_defs *at93c; > + > +static void at93c_reg_write(u32 val) > +{ > + *at93c->reg = val; > +} > + > +static u32 at93c_reg_read(void) > +{ > + u32 tmp = *at93c->reg; > + return tmp; > +} > + > +static u32 at93c_datareg_read(void) > +{ > + u32 tmp = *at93c->rdata_reg; > + return tmp; > +} > + > +static void at93c_cycle_clk(u32 data) > +{ > + at93c_reg_write(data | at93c->clk); > + lasat_ndelay(250); > + at93c_reg_write(data & ~at93c->clk); > + lasat_ndelay(250); > +} > + > +static void at93c_write_databit(u8 bit) > +{ > + u32 data = at93c_reg_read(); > + if (bit) > + data |= 1 << at93c->wdata_shift; > + else > + data &= ~(1 << at93c->wdata_shift); > + > + at93c_reg_write(data); > + lasat_ndelay(100); > + at93c_cycle_clk(data); > +} > + > +static unsigned int at93c_read_databit(void) > +{ > + u32 data; > + > + at93c_cycle_clk(at93c_reg_read()); > + data = (at93c_datareg_read() >> at93c->rdata_shift) & 1; > + return data; > +} > + > +static u8 at93c_read_byte(void) > +{ > + int i; > + u8 data = 0; > + > + for (i = 0; i<=7; i++) { > + data <<= 1; > + data |= at93c_read_databit(); > + } > + return data; > +} > + > +static void at93c_write_bits(u32 data, int size) > +{ > + int i; > + int shift = size - 1; > + u32 mask = (1 << shift); > + > + for (i = 0; i < size; i++) { > + at93c_write_databit((data & mask) >> shift); > + data <<= 1; > + } > +} > + > +static void at93c_init_op(void) > +{ > + at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift)); > + lasat_ndelay(50); > +} > + > +static void at93c_end_op(void) > +{ > + at93c_reg_write(at93c_reg_read() & ~at93c->cs); > + lasat_ndelay(250); > +} > + > +static void at93c_wait(void) > +{ > + at93c_init_op(); > + while (!at93c_read_databit()) > + ; > + at93c_end_op(); > +}; > + > +static void at93c_disable_wp(void) > +{ > + at93c_init_op(); > + at93c_write_bits(AT93C_WENCMD, 10); > + at93c_end_op(); > +} > + > +static void at93c_enable_wp(void) > +{ > + at93c_init_op(); > + at93c_write_bits(AT93C_WDSCMD, 10); > + at93c_end_op(); > +} > + > +u8 at93c_read(u8 addr) > +{ > + u8 byte; > + at93c_init_op(); > + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10); > + byte = at93c_read_byte(); > + at93c_end_op(); > + return byte; > +} > + > +void at93c_write(u8 addr, u8 data) > +{ > + at93c_disable_wp(); > + at93c_init_op(); > + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10); > + at93c_write_bits(data, 8); > + at93c_end_op(); > + at93c_wait(); > + at93c_enable_wp(); > +} > diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h > new file mode 100644 > index 0000000..cfe2f99 > --- /dev/null > +++ b/arch/mips/lasat/at93c.h > @@ -0,0 +1,18 @@ > +/* > + * Atmel AT93C46 serial eeprom driver > + * > + * Brian Murphy <brian.murphy@xxxxxxxxx> > + * > + */ > + > +extern struct at93c_defs { > + volatile u32 *reg; > + volatile u32 *rdata_reg; > + int rdata_shift; > + int wdata_shift; > + u32 cs; > + u32 clk; > +} *at93c; > + > +u8 at93c_read(u8 addr); > +void at93c_write(u8 addr, u8 data); > diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c > new file mode 100644 > index 0000000..7dced67 > --- /dev/null > +++ b/arch/mips/lasat/ds1603.c > @@ -0,0 +1,183 @@ > +/* > + * Dallas Semiconductors 1603 RTC driver > + * > + * Brian Murphy <brian@xxxxxxxxx> > + * > + */ > +#include <linux/kernel.h> > +#include <asm/lasat/lasat.h> > +#include <linux/delay.h> > +#include <asm/lasat/ds1603.h> > +#include <asm/time.h> > + > +#include "ds1603.h" > + > +#define READ_TIME_CMD 0x81 > +#define SET_TIME_CMD 0x80 > +#define TRIMMER_SET_CMD 0xC0 > +#define TRIMMER_VALUE_MASK 0x38 > +#define TRIMMER_SHIFT 3 > + > +struct ds_defs *ds1603 = NULL; No initializations of static variables to NULL or 0. This makes them end instead of .bss in .data where they will inflate the executable. > + > +/* HW specific register functions */ > +static void rtc_reg_write(unsigned long val) > +{ > + *ds1603->reg = val; > +} > + > +static unsigned long rtc_reg_read(void) > +{ > + unsigned long tmp = *ds1603->reg; > + return tmp; > +} > + > +static unsigned long rtc_datareg_read(void) > +{ > + unsigned long tmp = *ds1603->data_reg; > + return tmp; > +} > + > +static void rtc_nrst_high(void) > +{ > + rtc_reg_write(rtc_reg_read() | ds1603->rst); > +} > + > +static void rtc_nrst_low(void) > +{ > + rtc_reg_write(rtc_reg_read() & ~ds1603->rst); > +} > + > +static void rtc_cycle_clock(unsigned long data) > +{ > + data |= ds1603->clk; > + rtc_reg_write(data); > + lasat_ndelay(250); > + if (ds1603->data_reversed) > + data &= ~ds1603->data; > + else > + data |= ds1603->data; > + data &= ~ds1603->clk; > + rtc_reg_write(data); > + lasat_ndelay(250 + ds1603->huge_delay); > +} > + > +static void rtc_write_databit(unsigned int bit) > +{ > + unsigned long data = rtc_reg_read(); > + if (ds1603->data_reversed) > + bit = !bit; > + if (bit) > + data |= ds1603->data; > + else > + data &= ~ds1603->data; > + > + rtc_reg_write(data); > + lasat_ndelay(50 + ds1603->huge_delay); > + rtc_cycle_clock(data); > +} > + > +static unsigned int rtc_read_databit(void) > +{ > + unsigned int data; > + > + data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) > + >> ds1603->data_read_shift; > + rtc_cycle_clock(rtc_reg_read()); > + return data; > +} > + > +static void rtc_write_byte(unsigned int byte) > +{ > + int i; > + > + for (i = 0; i<=7; i++) { > + rtc_write_databit(byte & 1L); > + byte >>= 1; > + } > +} > + > +static void rtc_write_word(unsigned long word) > +{ > + int i; > + > + for (i = 0; i<=31; i++) { > + rtc_write_databit(word & 1L); > + word >>= 1; > + } > +} > + > +static unsigned long rtc_read_word(void) > +{ > + int i; > + unsigned long word = 0; > + unsigned long shift = 0; > + > + for (i = 0; i<=31; i++) { > + word |= rtc_read_databit() << shift; > + shift++; > + } > + return word; > +} > + > +static void rtc_init_op(void) > +{ > + rtc_nrst_high(); > + > + rtc_reg_write(rtc_reg_read() & ~ds1603->clk); > + > + lasat_ndelay(50); > +} > + > +static void rtc_end_op(void) > +{ > + rtc_nrst_low(); > + lasat_ndelay(1000); > +} > + > +/* interface */ > +unsigned long ds1603_read(void) > +{ > + unsigned long word; > + unsigned long flags; > + > + spin_lock_irqsave(&rtc_lock, flags); > + rtc_init_op(); > + rtc_write_byte(READ_TIME_CMD); > + word = rtc_read_word(); > + rtc_end_op(); > + spin_unlock_irqrestore(&rtc_lock, flags); > + return word; > +} > + > +int ds1603_set(unsigned long time) > +{ > + unsigned long flags; > + > + spin_lock_irqsave(&rtc_lock, flags); > + rtc_init_op(); > + rtc_write_byte(SET_TIME_CMD); > + rtc_write_word(time); > + rtc_end_op(); > + spin_unlock_irqrestore(&rtc_lock, flags); > + > + return 0; > +} > + > +void ds1603_set_trimmer(unsigned int trimval) > +{ > + rtc_init_op(); > + rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK) > + | (TRIMMER_SET_CMD)); > + rtc_end_op(); > +} > + > +void ds1603_disable(void) > +{ > + ds1603_set_trimmer(TRIMMER_DISABLE_RTC); > +} > + > +void ds1603_enable(void) > +{ > + ds1603_set_trimmer(TRIMMER_DEFAULT); > +} > diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h > new file mode 100644 > index 0000000..c2e5c76 > --- /dev/null > +++ b/arch/mips/lasat/ds1603.h > @@ -0,0 +1,33 @@ > +/* > + * Dallas Semiconductors 1603 RTC driver > + * > + * Brian Murphy <brian@xxxxxxxxx> > + * > + */ > +#ifndef __DS1603_H > +#define __DS1603_H > + > +struct ds_defs { > + volatile u32 *reg; > + volatile u32 *data_reg; > + u32 rst; > + u32 clk; > + u32 data; > + u32 data_read_shift; > + char data_reversed; > + u32 huge_delay; > +}; > + > +extern struct ds_defs *ds1603; > + > +unsigned long ds1603_read(void); > +int ds1603_set(unsigned long); > +void ds1603_set_trimmer(unsigned int); > +void ds1603_enable(void); > +void ds1603_disable(void); > +void ds1603_init(struct ds_defs *); > + > +#define TRIMMER_DEFAULT 3 > +#define TRIMMER_DISABLE_RTC 0 > + > +#endif > diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile > new file mode 100644 > index 0000000..5332449 > --- /dev/null > +++ b/arch/mips/lasat/image/Makefile > @@ -0,0 +1,54 @@ > +# > +# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER > +# > +# i-data Networks > +# > +# Author: Thomas Horsten <thh@xxxxxxxxxx> > +# > + > +ifndef Version > + Version = "$(USER)-test" > +endif > + > +MKLASATIMG = mklasatimg > +MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 > +KERNEL_IMAGE = $(TOPDIR)/vmlinux > +KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ ) > +KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) > + > +LDSCRIPT= -L$(obj) -Tromscript.normal > + > +HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \ > + -D_kernel_entry=0x$(KERNEL_ENTRY) \ > + -D VERSION="\"$(Version)\"" \ > + -D TIMESTAMP=$(shell date +%s) > + > +$(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE) > + $(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $< > + > +OBJECTS = head.o kImage.o > + > +rom.sw: $(obj)/rom.sw > +rom.bin: $(obj)/rom.bin > + > +$(obj)/rom.sw: $(obj)/rom.bin > + $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH) > + > +$(obj)/rom.bin: $(obj)/rom > + $(OBJCOPY) -O binary -S $^ $@ > + > +# Rule to make the bootloader > +$(obj)/rom: $(addprefix $(obj)/,$(OBJECTS)) > + $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^ > + > +$(obj)/%.o: $(obj)/%.gz > + $(LD) -r -o $@ -b binary $< > + > +$(obj)/%.gz: $(obj)/%.bin > + gzip -cf -9 $< > $@ > + > +$(obj)/kImage.bin: $(KERNEL_IMAGE) > + $(OBJCOPY) -O binary -S $^ $@ > + > +clean: > + rm -f rom rom.bin rom.sw kImage.bin kImage.o > diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S > new file mode 100644 > index 0000000..efb95f2 > --- /dev/null > +++ b/arch/mips/lasat/image/head.S > @@ -0,0 +1,31 @@ > +#include <asm/lasat/head.h> > + > + .text > + .section .text.start, "ax" > + .set noreorder > + .set mips3 > + > + /* Magic words identifying a software image */ > + .word LASAT_K_MAGIC0_VAL > + .word LASAT_K_MAGIC1_VAL > + > + /* Image header version */ > + .word 0x00000002 > + > + /* image start and size */ > + .word _image_start > + .word _image_size > + > + /* start of kernel and entrypoint in uncompressed image */ > + .word _kernel_start > + .word _kernel_entry > + > + /* Here we have room for future flags */ > + > + .org 0x40 > +reldate: > + .word TIMESTAMP > + > + .org 0x50 > +release: > + .string VERSION > diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal > new file mode 100644 > index 0000000..988f8ad > --- /dev/null > +++ b/arch/mips/lasat/image/romscript.normal > @@ -0,0 +1,23 @@ > +OUTPUT_ARCH(mips) > + > +SECTIONS > +{ > + .text : > + { > + *(.text.start) > + } > + > + /* Data in ROM */ > + > + .data ALIGN(0x10) : > + { > + *(.data) > + } > + _image_start = ADDR(.data); > + _image_size = SIZEOF(.data); > + > + .other : > + { > + *(.*) > + } > +} > diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c > new file mode 100644 > index 0000000..9a622b9 > --- /dev/null > +++ b/arch/mips/lasat/interrupt.c > @@ -0,0 +1,130 @@ > +/* > + * Carsten Langgaard, carstenl@xxxxxxxx > + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. > + * > + * This program is free software; you can distribute it and/or modify it > + * under the terms of the GNU General Public License (Version 2) as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * Routines for generic manipulation of the interrupts found on the > + * Lasat boards. > + */ > +#include <linux/init.h> > +#include <linux/sched.h> > +#include <linux/slab.h> > +#include <linux/interrupt.h> > +#include <linux/kernel_stat.h> > + > +#include <asm/bootinfo.h> > +#include <asm/irq.h> > +#include <asm/lasat/lasatint.h> > +#include <asm/time.h> > +#include <asm/gdb-stub.h> > + > +static volatile int *lasat_int_status = NULL; > +static volatile int *lasat_int_mask = NULL; > +static volatile int lasat_int_mask_shift; > + > +void disable_lasat_irq(unsigned int irq_nr) > +{ > + *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; > +} > + > +void enable_lasat_irq(unsigned int irq_nr) > +{ > + *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; > +} > + > +static struct irq_chip lasat_irq_type = { > + .name = "Lasat", > + .ack = disable_lasat_irq, > + .mask = disable_lasat_irq, > + .mask_ack = disable_lasat_irq, > + .unmask = enable_lasat_irq, > +}; > + > +static inline int ls1bit32(unsigned int x) > +{ > + int b = 31, s; > + > + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; > + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; > + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; > + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; > + s = 1; if (x << 1 == 0) s = 0; b -= s; > + > + return b; > +} > + > +static unsigned long (* get_int_status)(void); > + > +static unsigned long get_int_status_100(void) > +{ > + return *lasat_int_status & *lasat_int_mask; > +} > + > +static unsigned long get_int_status_200(void) > +{ > + unsigned long int_status; > + > + int_status = *lasat_int_status; > + int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff; > + return int_status; > +} > + > +asmlinkage void plat_irq_dispatch(void) > +{ > + unsigned long int_status; > + unsigned int cause = read_c0_cause(); > + int irq; > + > + if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ > + ll_timer_interrupt(7); > + return; > + } > + > + int_status = get_int_status(); > + > + /* if int_status == 0, then the interrupt has already been cleared */ > + if (int_status) { > + irq = ls1bit32(int_status); > + > + do_IRQ(irq); > + } > +} > + > +void __init arch_init_irq(void) > +{ > + int i; > + > + switch (mips_machtype) { > + case MACH_LASAT_100: > + lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; > + lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; > + lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; > + get_int_status = get_int_status_100; > + *lasat_int_mask = 0; > + break; > + case MACH_LASAT_200: > + lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; > + lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; > + lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; > + get_int_status = get_int_status_200; > + *lasat_int_mask &= 0xffff; > + break; > + default: > + panic("arch_init_irq: mips_machtype incorrect"); > + } > + > + for (i = 0; i <= LASATINT_END; i++) > + set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); > +} > diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c > new file mode 100644 > index 0000000..fbe9a87 > --- /dev/null > +++ b/arch/mips/lasat/lasat_board.c > @@ -0,0 +1,279 @@ > +/* > + * Thomas Horsten <thh@xxxxxxxxx> > + * Copyright (C) 2000 LASAT Networks A/S. > + * > + * This program is free software; you can distribute it and/or modify it > + * under the terms of the GNU General Public License (Version 2) as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * Routines specific to the LASAT boards > + */ > +#include <linux/types.h> > +#include <linux/crc32.h> > +#include <asm/lasat/lasat.h> > +#include <linux/kernel.h> > +#include <linux/string.h> > +#include <linux/ctype.h> > +#include <asm/bootinfo.h> > +#include <asm/addrspace.h> > +#include "at93c.h" > +/* New model description table */ > +#include "lasat_models.h" > + > +#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len)) Complicated method for ~crc32(~0, data, len)? > + > +struct lasat_info lasat_board_info; > + > +void update_bcastaddr(void); > + > +int EEPROMRead(unsigned int pos, unsigned char *data, int len) > +{ > + int i; > + > + for (i=0; i<len; i++) > + *data++ = at93c_read(pos++); > + > + return 0; > +} > +int EEPROMWrite(unsigned int pos, unsigned char *data, int len) > +{ > + int i; > + > + for (i=0; i<len; i++) > + at93c_write(pos++, *data++); > + > + return 0; > +} > + > +static void init_flash_sizes(void) > +{ > + int i; > + unsigned long *lb = lasat_board_info.li_flashpart_base; > + unsigned long *ls = lasat_board_info.li_flashpart_size; > + > + ls[LASAT_MTD_BOOTLOADER] = 0x40000; > + ls[LASAT_MTD_SERVICE] = 0xC0000; > + ls[LASAT_MTD_NORMAL] = 0x100000; > + > + if (mips_machtype == MACH_LASAT_100) { > + lasat_board_info.li_flash_base = 0x1e000000; > + > + lb[LASAT_MTD_BOOTLOADER] = 0x1e400000; > + > + if (lasat_board_info.li_flash_size > 0x200000) { > + ls[LASAT_MTD_CONFIG] = 0x100000; > + ls[LASAT_MTD_FS] = 0x500000; > + } > + } else { > + lasat_board_info.li_flash_base = 0x10000000; > + > + if (lasat_board_info.li_flash_size < 0x1000000) { > + lb[LASAT_MTD_BOOTLOADER] = 0x10000000; > + ls[LASAT_MTD_CONFIG] = 0x100000; > + if (lasat_board_info.li_flash_size >= 0x400000) { > + ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000; > + } > + } > + } > + > + for (i = 1; i < LASAT_MTD_LAST; i++) > + lb[i] = lb[i-1] + ls[i-1]; > +} > + > +int lasat_init_board_info(void) > +{ > + int c; > + unsigned long crc; > + unsigned long cfg0, cfg1; > + const product_info_t *ppi; > + int i_n_base_models = N_BASE_MODELS; > + const char * const * i_txt_base_models = txt_base_models; > + int i_n_prids = N_PRIDS; > + > + memset(&lasat_board_info, 0, sizeof(lasat_board_info)); > + > + /* First read the EEPROM info */ > + EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, > + sizeof(struct lasat_eeprom_struct)); > + > + /* Check the CRC */ > + crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), > + sizeof(struct lasat_eeprom_struct) - 4); > + > + if (crc != lasat_board_info.li_eeprom_info.crc32) { > + printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does " > + "not match calculated, attempting to soldier on...\n"); > + } > + > + if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) { > + printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version " > + "%d, wanted version %d, attempting to soldier on...\n", > + (unsigned int)lasat_board_info.li_eeprom_info.version, > + LASAT_EEPROM_VERSION); > + } > + > + cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; > + cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; > + > + if ( LASAT_W0_DSCTYPE(cfg0) != 1) { > + printk(KERN_WARNING "WARNING...\nWARNING...\n" > + "Invalid configuration read from EEPROM, attempting to " > + "soldier on..."); > + } > + /* We have a valid configuration */ > + > + switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { > + case 0: > + lasat_board_info.li_memsize = 0x0800000; > + break; > + case 1: > + lasat_board_info.li_memsize = 0x1000000; > + break; > + case 2: > + lasat_board_info.li_memsize = 0x2000000; > + break; > + case 3: > + lasat_board_info.li_memsize = 0x4000000; > + break; > + case 4: > + lasat_board_info.li_memsize = 0x8000000; > + break; > + default: > + lasat_board_info.li_memsize = 0; > + } > + > + switch (LASAT_W0_SDRAMBANKS(cfg0)) { > + case 0: > + break; > + case 1: > + lasat_board_info.li_memsize *= 2; > + break; > + default: > + break; > + } > + > + switch (LASAT_W0_BUSSPEED(cfg0)) { > + case 0x0: > + lasat_board_info.li_bus_hz = 60000000; > + break; > + case 0x1: > + lasat_board_info.li_bus_hz = 66000000; > + break; > + case 0x2: > + lasat_board_info.li_bus_hz = 66666667; > + break; > + case 0x3: > + lasat_board_info.li_bus_hz = 80000000; > + break; > + case 0x4: > + lasat_board_info.li_bus_hz = 83333333; > + break; > + case 0x5: > + lasat_board_info.li_bus_hz = 100000000; > + break; > + } > + > + switch (LASAT_W0_CPUCLK(cfg0)) { > + case 0x0: > + lasat_board_info.li_cpu_hz = > + lasat_board_info.li_bus_hz; > + break; > + case 0x1: > + lasat_board_info.li_cpu_hz = > + lasat_board_info.li_bus_hz + > + (lasat_board_info.li_bus_hz >> 1); > + break; > + case 0x2: > + lasat_board_info.li_cpu_hz = > + lasat_board_info.li_bus_hz + > + lasat_board_info.li_bus_hz; > + break; > + case 0x3: > + lasat_board_info.li_cpu_hz = > + lasat_board_info.li_bus_hz + > + lasat_board_info.li_bus_hz + > + (lasat_board_info.li_bus_hz >> 1); > + break; > + case 0x4: > + lasat_board_info.li_cpu_hz = > + lasat_board_info.li_bus_hz + > + lasat_board_info.li_bus_hz + > + lasat_board_info.li_bus_hz; > + break; > + } > + > + /* Flash size */ > + switch (LASAT_W1_FLASHSIZE(cfg1)) { > + case 0: > + lasat_board_info.li_flash_size = 0x200000; > + break; > + case 1: > + lasat_board_info.li_flash_size = 0x400000; > + break; > + case 2: > + lasat_board_info.li_flash_size = 0x800000; > + break; > + case 3: > + lasat_board_info.li_flash_size = 0x1000000; > + break; > + case 4: > + lasat_board_info.li_flash_size = 0x2000000; > + break; > + } > + > + init_flash_sizes(); > + > + lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); > + lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; > + if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) > + lasat_board_info.li_prid = lasat_board_info.li_bmid; > + > + /* Base model stuff */ > + if (lasat_board_info.li_bmid > i_n_base_models) > + lasat_board_info.li_bmid = i_n_base_models; > + strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]); > + > + /* Product ID dependent values */ > + c = lasat_board_info.li_prid; > + if (c >= i_n_prids) { > + strcpy(lasat_board_info.li_namestr, "Unknown Model"); > + strcpy(lasat_board_info.li_typestr, "Unknown Type"); > + } else { > + ppi = &vendor_info_table[0].vi_product_info[c]; > + strcpy(lasat_board_info.li_namestr, ppi->pi_name); > + if (ppi->pi_type) > + strcpy(lasat_board_info.li_typestr, ppi->pi_type); > + else > + sprintf(lasat_board_info.li_typestr, "%d",10*c); > + } > + > +#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) > + update_bcastaddr(); > +#endif > + > + return 0; > +} > + > +void lasat_write_eeprom_info(void) > +{ > + unsigned long crc; > + > + /* Generate the CRC */ > + crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), > + sizeof(struct lasat_eeprom_struct) - 4); > + lasat_board_info.li_eeprom_info.crc32 = crc; > + > + /* Write the EEPROM info */ > + EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, > + sizeof(struct lasat_eeprom_struct)); > +} > + > diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h > new file mode 100644 > index 0000000..ae0c5d0 > --- /dev/null > +++ b/arch/mips/lasat/lasat_models.h > @@ -0,0 +1,63 @@ > +/* > + * Model description tables > + */ > + > +typedef struct product_info_t { No typdefs. > + const char *pi_name; > + const char *pi_type; > +} product_info_t; > + > +typedef struct vendor_info_t { > + const char *vi_name; > + const product_info_t *vi_product_info; > +} vendor_info_t; > + > +/* > + * Base models > + */ > +static const char * const txt_base_models[] = { > + "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown" > +}; > +#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1) > + > +/* > + * Eicon Networks > + */ > +static const char txt_en_mq[] = "Masquerade"; > +static const char txt_en_sp[] = "Safepipe"; > + > +static const product_info_t product_info_eicon[] = { > + { txt_en_mq, "II" }, /* 0 */ > + { txt_en_mq, "Pro" }, /* 1 */ > + { txt_en_sp, "25" }, /* 2 */ > + { txt_en_sp, "50" }, /* 3 */ > + { txt_en_sp, "100" }, /* 4 */ > + { txt_en_sp, "5000" }, /* 5 */ > + { txt_en_sp, "7000" }, /* 6 */ > + { txt_en_sp, "30" }, /* 7 */ > + { txt_en_sp, "5100" }, /* 8 */ > + { txt_en_sp, "7100" }, /* 9 */ > + { txt_en_sp, "1110" }, /* 10 */ > + { txt_en_sp, "3020" }, /* 11 */ > + { txt_en_sp, "3030" }, /* 12 */ > + { txt_en_sp, "5020" }, /* 13 */ > + { txt_en_sp, "5030" }, /* 14 */ > + { txt_en_sp, "1120" }, /* 15 */ > + { txt_en_sp, "1130" }, /* 16 */ > + { txt_en_sp, "6010" }, /* 17 */ > + { txt_en_sp, "6110" }, /* 18 */ > + { txt_en_sp, "6210" }, /* 19 */ > + { txt_en_sp, "1020" }, /* 20 */ > + { txt_en_sp, "1040" }, /* 21 */ > + { txt_en_sp, "1050" }, /* 22 */ > + { txt_en_sp, "1060" }, /* 23 */ > +}; > +#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t)) > + > +/* > + * The vendor table > + */ > +static vendor_info_t const vendor_info_table[] = { > + { "Eicon Networks", product_info_eicon }, > +}; > +#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t)) > diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c > new file mode 100644 > index 0000000..9ae82c3 > --- /dev/null > +++ b/arch/mips/lasat/picvue.c > @@ -0,0 +1,240 @@ > +/* > + * Picvue PVC160206 display driver > + * > + * Brian Murphy <brian@xxxxxxxxx> > + * > + */ > +#include <linux/kernel.h> > +#include <linux/delay.h> > +#include <asm/bootinfo.h> > +#include <asm/lasat/lasat.h> > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/errno.h> > +#include <linux/string.h> > + > +#include "picvue.h" > + > +#define PVC_BUSY 0x80 > +#define PVC_NLINES 2 > +#define PVC_DISPMEM 80 > +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES > + > +struct pvc_defs *picvue = NULL; > + > +DECLARE_MUTEX(pvc_sem); > + > +static void pvc_reg_write(u32 val) > +{ > + *picvue->reg = val; > +} > + > +static u32 pvc_reg_read(void) > +{ > + u32 tmp = *picvue->reg; > + return tmp; > +} > + > +static void pvc_write_byte(u32 data, u8 byte) > +{ > + data |= picvue->e; > + pvc_reg_write(data); > + data &= ~picvue->data_mask; > + data |= byte << picvue->data_shift; > + pvc_reg_write(data); > + ndelay(220); > + pvc_reg_write(data & ~picvue->e); > + ndelay(220); > +} > + > +static u8 pvc_read_byte(u32 data) > +{ > + u8 byte; > + > + data |= picvue->e; > + pvc_reg_write(data); > + ndelay(220); > + byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift; > + data &= ~picvue->e; > + pvc_reg_write(data); > + ndelay(220); > + return byte; > +} > + > +static u8 pvc_read_data(void) > +{ > + u32 data = pvc_reg_read(); > + u8 byte; > + data |= picvue->rw; > + data &= ~picvue->rs; > + pvc_reg_write(data); > + ndelay(40); > + byte = pvc_read_byte(data); > + data |= picvue->rs; > + pvc_reg_write(data); > + return byte; > +} > + > +#define TIMEOUT 1000 > +static int pvc_wait(void) > +{ > + int i = TIMEOUT; > + int err = 0; > + > + while ((pvc_read_data() & PVC_BUSY) && i) > + i--; > + if (i == 0) > + err = -ETIME; > + > + return err; > +} > + > +#define MODE_INST 0 > +#define MODE_DATA 1 > +static void pvc_write(u8 byte, int mode) > +{ > + u32 data = pvc_reg_read(); > + data &= ~picvue->rw; > + if (mode == MODE_DATA) > + data |= picvue->rs; > + else > + data &= ~picvue->rs; > + pvc_reg_write(data); > + ndelay(40); > + pvc_write_byte(data, byte); > + if (mode == MODE_DATA) > + data &= ~picvue->rs; > + else > + data |= picvue->rs; > + pvc_reg_write(data); > + pvc_wait(); > +} > + > +void pvc_write_string(const unsigned char *str, u8 addr, int line) > +{ > + int i = 0; > + > + if (line > 0 && (PVC_NLINES > 1)) > + addr += 0x40 * line; > + pvc_write(0x80 | addr, MODE_INST); > + > + while (*str != 0 && i < PVC_LINELEN) { > + pvc_write(*str++, MODE_DATA); > + i++; > + } > +} > + > +void pvc_write_string_centered(const unsigned char *str, int line) > +{ > + int len = strlen(str); > + u8 addr; > + > + if (len > PVC_VISIBLE_CHARS) > + addr = 0; > + else > + addr = (PVC_VISIBLE_CHARS - strlen(str))/2; > + > + pvc_write_string(str, addr, line); > +} > + > +void pvc_dump_string(const unsigned char *str) > +{ > + int len = strlen(str); > + > + pvc_write_string(str, 0, 0); > + if (len > PVC_VISIBLE_CHARS) > + pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1); > +} > + > +#define BM_SIZE 8 > +#define MAX_PROGRAMMABLE_CHARS 8 > +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]) > +{ > + int i; > + int addr; > + > + if (charnum > MAX_PROGRAMMABLE_CHARS) > + return -ENOENT; > + > + addr = charnum * 8; > + pvc_write(0x40 | addr, MODE_INST); > + > + for (i=0; i<BM_SIZE; i++) > + pvc_write(bitmap[i], MODE_DATA); > + return 0; > +} > + > +#define FUNC_SET_CMD 0x20 > +#define EIGHT_BYTE (1 << 4) > +#define FOUR_BYTE 0 > +#define TWO_LINES (1 << 3) > +#define ONE_LINE 0 > +#define LARGE_FONT (1 << 2) > +#define SMALL_FONT 0 > +static void pvc_funcset(u8 cmd) > +{ > + pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)), MODE_INST); > +} > + > +#define ENTRYMODE_CMD 0x4 > +#define AUTO_INC (1 << 1) > +#define AUTO_DEC 0 > +#define CURSOR_FOLLOWS_DISP (1 << 0) > +static void pvc_entrymode(u8 cmd) > +{ > + pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)), MODE_INST); > +} > + > +#define DISP_CNT_CMD 0x08 > +#define DISP_OFF 0 > +#define DISP_ON (1 << 2) > +#define CUR_ON (1 << 1) > +#define CUR_BLINK (1 << 0) > +void pvc_dispcnt(u8 cmd) > +{ > + pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST); > +} > + > +#define MOVE_CMD 0x10 > +#define DISPLAY (1 << 3) > +#define CURSOR 0 > +#define RIGHT (1 << 2) > +#define LEFT 0 > +void pvc_move(u8 cmd) > +{ > + pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST); > +} > + > +#define CLEAR_CMD 0x1 > +void pvc_clear(void) > +{ > + pvc_write(CLEAR_CMD, MODE_INST); > +} > + > +#define HOME_CMD 0x2 > +void pvc_home(void) > +{ > + pvc_write(HOME_CMD, MODE_INST); > +} > + > +int pvc_init(void) > +{ > + u8 cmd = EIGHT_BYTE; > + > + if (PVC_NLINES == 2) > + cmd |= (SMALL_FONT|TWO_LINES); > + else > + cmd |= (LARGE_FONT|ONE_LINE); > + pvc_funcset(cmd); > + pvc_dispcnt(DISP_ON); > + pvc_entrymode(AUTO_INC); > + > + pvc_clear(); > + pvc_write_string_centered("Display", 0); > + pvc_write_string_centered("Initialized", 1); > + > + return 0; > +} > + > +module_init(pvc_init); > +MODULE_LICENSE("GPL"); > diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h > new file mode 100644 > index 0000000..2a96bf9 > --- /dev/null > +++ b/arch/mips/lasat/picvue.h > @@ -0,0 +1,48 @@ > +/* > + * Picvue PVC160206 display driver > + * > + * Brian Murphy <brian.murphy@xxxxxxxxx> > + * > + */ > +#include <asm/semaphore.h> > + > +struct pvc_defs { > + volatile u32 *reg; > + u32 data_shift; > + u32 data_mask; > + u32 e; > + u32 rw; > + u32 rs; > +}; > + > +extern struct pvc_defs *picvue; > + > +#define PVC_NLINES 2 > +#define PVC_DISPMEM 80 > +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES > +#define PVC_VISIBLE_CHARS 16 > + > +void pvc_write_string(const unsigned char *str, u8 addr, int line); > +void pvc_write_string_centered(const unsigned char *str, int line); > +void pvc_dump_string(const unsigned char *str); > + > +#define BM_SIZE 8 > +#define MAX_PROGRAMMABLE_CHARS 8 > +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]); > + > +void pvc_dispcnt(u8 cmd); > +#define DISP_OFF 0 > +#define DISP_ON (1 << 2) > +#define CUR_ON (1 << 1) > +#define CUR_BLINK (1 << 0) > + > +void pvc_move(u8 cmd); > +#define DISPLAY (1 << 3) > +#define CURSOR 0 > +#define RIGHT (1 << 2) > +#define LEFT 0 > + > +void pvc_clear(void); > +void pvc_home(void); > + > +extern struct semaphore pvc_sem; > diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c > new file mode 100644 > index 0000000..cce7cdd > --- /dev/null > +++ b/arch/mips/lasat/picvue_proc.c > @@ -0,0 +1,186 @@ > +/* > + * Picvue PVC160206 display driver > + * > + * Brian Murphy <brian.murphy@xxxxxxxxx> > + * > + */ > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/errno.h> > + > +#include <linux/proc_fs.h> > +#include <linux/interrupt.h> > + > +#include <linux/timer.h> > + > +#include "picvue.h" > + > +static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; > +static int pvc_linedata[PVC_NLINES]; > +static struct proc_dir_entry *pvc_display_dir; > +static char *pvc_linename[PVC_NLINES] = {"line1", "line2"}; > +#define DISPLAY_DIR_NAME "display" > +static int scroll_dir = 0, scroll_interval = 0; > + > +static struct timer_list timer; > + > +static void pvc_display(unsigned long data) { > + int i; > + > + pvc_clear(); > + for (i=0; i<PVC_NLINES; i++) > + pvc_write_string(pvc_lines[i], 0, i); > +} > + > +static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0); > + > +static int pvc_proc_read_line(char *page, char **start, > + off_t off, int count, > + int *eof, void *data) > +{ > + char *origpage = page; Plenty of places were doing indentation with spaces not tabs, fixed. > + int lineno = *(int *)data; > + > + if (lineno < 0 || lineno > PVC_NLINES) { > + printk("proc_read_line: invalid lineno %d\n", lineno); > + return 0; > + } > + > + down(&pvc_sem); > + page += sprintf(page, "%s\n", pvc_lines[lineno]); > + up(&pvc_sem); > + > + return page - origpage; > +} > + > +static int pvc_proc_write_line(struct file *file, const char *buffer, > + unsigned long count, void *data) > +{ > + int origcount = count; > + int lineno = *(int *)data; > + > + if (lineno < 0 || lineno > PVC_NLINES) { > + printk("proc_write_line: invalid lineno %d\n", lineno); > + return origcount; > + } > + > + if (count > PVC_LINELEN) > + count = PVC_LINELEN; > + > + if (buffer[count-1] == '\n') > + count--; > + > + down(&pvc_sem); > + strncpy(pvc_lines[lineno], buffer, count); > + pvc_lines[lineno][count] = '\0'; > + up(&pvc_sem); > + > + tasklet_schedule(&pvc_display_tasklet); > + > + return origcount; > +} > + > +static int pvc_proc_write_scroll(struct file *file, const char *buffer, > + unsigned long count, void *data) > +{ > + int origcount = count; > + int cmd = simple_strtol(buffer, NULL, 10); > + > + down(&pvc_sem); > + if (scroll_interval != 0) > + del_timer(&timer); > + > + if (cmd == 0) { > + scroll_dir = 0; > + scroll_interval = 0; > + } else { > + if (cmd < 0) { > + scroll_dir = -1; > + scroll_interval = -cmd; > + } else { > + scroll_dir = 1; > + scroll_interval = cmd; > + } > + add_timer(&timer); > + } > + up(&pvc_sem); > + > + return origcount; > +} > + > +static int pvc_proc_read_scroll(char *page, char **start, > + off_t off, int count, > + int *eof, void *data) > +{ > + char *origpage = page; > + > + down(&pvc_sem); > + page += sprintf(page, "%d\n", scroll_dir * scroll_interval); > + up(&pvc_sem); > + > + return page - origpage; > +} > + > + > +void pvc_proc_timerfunc(unsigned long data) > +{ > + if (scroll_dir < 0) > + pvc_move(DISPLAY|RIGHT); > + else if (scroll_dir > 0) > + pvc_move(DISPLAY|LEFT); > + > + timer.expires = jiffies + scroll_interval; > + add_timer(&timer); > +} > + > +static void pvc_proc_cleanup(void) > +{ > + int i; > + for (i=0; i<PVC_NLINES; i++) > + remove_proc_entry(pvc_linename[i], pvc_display_dir); > + remove_proc_entry("scroll", pvc_display_dir); > + remove_proc_entry(DISPLAY_DIR_NAME, NULL); > + > + del_timer(&timer); > +} > + > +static int __init pvc_proc_init(void) > +{ > + struct proc_dir_entry *proc_entry; > + int i; > + > + pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL); > + if (pvc_display_dir == NULL) > + goto error; > + > + for (i=0; i<PVC_NLINES; i++) { > + strcpy(pvc_lines[i], ""); > + pvc_linedata[i] = i; > + } > + for (i=0; i<PVC_NLINES; i++) { > + proc_entry = create_proc_entry(pvc_linename[i], 0644, pvc_display_dir); > + if (proc_entry == NULL) > + goto error; > + proc_entry->read_proc = pvc_proc_read_line; > + proc_entry->write_proc = pvc_proc_write_line; > + proc_entry->data = &pvc_linedata[i]; > + } > + proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); > + if (proc_entry == NULL) > + goto error; > + proc_entry->write_proc = pvc_proc_write_scroll; > + proc_entry->read_proc = pvc_proc_read_scroll; > + > + init_timer(&timer); > + timer.function = pvc_proc_timerfunc; > + > + return 0; > +error: > + pvc_proc_cleanup(); > + return -ENOMEM; > +} > + > +module_init(pvc_proc_init); > +module_exit(pvc_proc_cleanup); > +MODULE_LICENSE("GPL"); > diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c > new file mode 100644 > index 0000000..812c6ac > --- /dev/null > +++ b/arch/mips/lasat/prom.c > @@ -0,0 +1,117 @@ > +/* > + * PROM interface routines. > + */ > +#include <linux/types.h> > +#include <linux/init.h> > +#include <linux/string.h> > +#include <linux/ctype.h> > +#include <linux/kernel.h> > +#include <linux/mm.h> > +#include <linux/bootmem.h> > +#include <linux/ioport.h> > +#include <asm/bootinfo.h> > +#include <asm/lasat/lasat.h> > +#include <asm/cpu.h> > + > +#include "at93c.h" > +#include <asm/lasat/eeprom.h> > +#include "prom.h" > + > +#define RESET_VECTOR 0xbfc00000 > +#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n)) > +#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0) > +#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) > +#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) > + > +static void null_prom_display(const char *string, int pos, int clear) > +{ > +} > + > +static void null_prom_monitor(void) > +{ > +} > + > +static void null_prom_putc(char c) > +{ > +} > + > +/* these are functions provided by the bootloader */ > +static void (* __prom_putc)(char c) = null_prom_putc; > + > +void prom_putchar(char c) > +{ > + __prom_putc(c); > +} > + > +void (* prom_display)(const char *string, int pos, int clear) = > + null_prom_display; > +void (* prom_monitor)(void) = null_prom_monitor; > + > +unsigned int lasat_ndelay_divider; > + > +static void setup_prom_vectors(void) > +{ > + u32 version = *(u32 *)(RESET_VECTOR + 0x90); > + > + if (version >= 307) { > + prom_display = (void *)PROM_DISPLAY_ADDR; > + __prom_putc = (void *)PROM_PUTC_ADDR; > + prom_monitor = (void *)PROM_MONITOR_ADDR; > + } > + printk("prom vectors set up\n"); > +} > + > +static struct at93c_defs at93c_defs[N_MACHTYPES] = { > + {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100, > + AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100}, > + {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200, > + AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200}, Lines longer than 80 characters and certainly this struct gets more readable from ISO initializers. > +}; > + > +void __init prom_init(void) > +{ > + int argc = fw_arg0; > + char **argv = (char **) fw_arg1; > + > + setup_prom_vectors(); > + > + if (current_cpu_data.cputype == CPU_R5000) { > + printk("LASAT 200 board\n"); > + mips_machtype = MACH_LASAT_200; > + lasat_ndelay_divider = LASAT_200_DIVIDER; > + } else { > + printk("LASAT 100 board\n"); > + mips_machtype = MACH_LASAT_100; > + lasat_ndelay_divider = LASAT_100_DIVIDER; > + } > + > + at93c = &at93c_defs[mips_machtype]; > + > + lasat_init_board_info(); /* Read info from EEPROM */ > + > + mips_machgroup = MACH_GROUP_LASAT; > + > + /* Get the command line */ > + if (argc > 0) { > + strncpy(arcs_cmdline, argv[0], CL_SIZE-1); > + arcs_cmdline[CL_SIZE-1] = '\0'; > + } > + > + /* Set the I/O base address */ > + set_io_port_base(KSEG1); > + > + /* Set memory regions */ > + ioport_resource.start = 0; > + ioport_resource.end = 0xffffffff; /* Wrong, fixme. */ > + > + add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM); > +} > + > +void __init prom_free_prom_memory(void) > +{ > +} > + > +const char *get_system_type(void) > +{ > + return lasat_board_info.li_bmstr; > +} > diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h > new file mode 100644 > index 0000000..019d45f > --- /dev/null > +++ b/arch/mips/lasat/prom.h > @@ -0,0 +1,5 @@ > +#ifndef PROM_H > +#define PROM_H > +extern void (* prom_display)(const char *string, int pos, int clear); > +extern void (* prom_monitor)(void); > +#endif > diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c > new file mode 100644 > index 0000000..9e22acf > --- /dev/null > +++ b/arch/mips/lasat/reset.c > @@ -0,0 +1,69 @@ > +/* > + * Thomas Horsten <thh@xxxxxxxxx> > + * Copyright (C) 2000 LASAT Networks A/S. > + * > + * This program is free software; you can distribute it and/or modify it > + * under the terms of the GNU General Public License (Version 2) as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * Reset the LASAT board. > + */ > +#include <linux/kernel.h> > +#include <linux/pm.h> > + > +#include <asm/reboot.h> > +#include <asm/system.h> > +#include <asm/lasat/lasat.h> > + > +#include "picvue.h" > +#include "prom.h" > + > +static void lasat_machine_restart(char *command); > +static void lasat_machine_halt(void); > + > +/* Used to set machine to boot in service mode via /proc interface */ > +int lasat_boot_to_service = 0; > + > +static void lasat_machine_restart(char *command) > +{ > + local_irq_disable(); > + > + if (lasat_boot_to_service) { > + printk("machine_restart: Rebooting to service mode\n"); The reboot/restart functions shouldn't print any messages. If that is desired, userspace should do so. > + *(volatile unsigned int *)0xa0000024 = 0xdeadbeef; > + *(volatile unsigned int *)0xa00000fc = 0xfedeabba; > + } > + *lasat_misc->reset_reg = 0xbedead; > + for (;;) ; > +} > + > +#define MESSAGE "System halted" > +static void lasat_machine_halt(void) > +{ > + local_irq_disable(); > + > + /* Disable interrupts and loop forever */ > + printk(KERN_NOTICE MESSAGE "\n"); > +#ifdef CONFIG_PICVUE > + pvc_clear(); > + pvc_write_string(MESSAGE, 0, 0); > +#endif The reboot/restart functions shouldn't print any messages. If that is desired, userspace should do so. > + prom_monitor(); > + for (;;) ; > +} > + > +void lasat_reboot_setup(void) > +{ > + _machine_restart = lasat_machine_restart; > + _machine_halt = lasat_machine_halt; > + pm_power_off = lasat_machine_halt; > +} > diff --git a/arch/mips/lasat/serial.c b/arch/mips/lasat/serial.c > new file mode 100644 > index 0000000..bfc0deb > --- /dev/null > +++ b/arch/mips/lasat/serial.c > @@ -0,0 +1,93 @@ > +/* > + * Registration of Lasat UART platform device. > + * > + * Copyright (C) 2007 Brian Murphy <brian@xxxxxxxxx> > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Please stick to the 80 columns limit. That's valid even for the GPL ;-) > + */ > +#include <linux/errno.h> > +#include <linux/init.h> > +#include <linux/ioport.h> > +#include <linux/platform_device.h> > +#include <linux/serial_8250.h> > + > +#include <asm/bootinfo.h> > +#include <asm/lasat/lasat.h> > +#include <asm/lasat/serial.h> > + > +static struct resource lasat_serial_res[2] __initdata; > + > +static struct plat_serial8250_port lasat_serial8250_port[] = { > + { > + .iotype = UPIO_MEM, > + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, > + }, > + {}, > +}; > + > +static __init int lasat_uart_add(void) > +{ > + struct platform_device *pdev; > + int retval; > + > + pdev = platform_device_alloc("serial8250", -1); > + if (!pdev) > + return -ENOMEM; > + > + if (mips_machtype == MACH_LASAT_100) { > + lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_100); > + lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_100 * 8 - 1; > + lasat_serial_res[0].flags = IORESOURCE_MEM; > + lasat_serial_res[1].start = LASATINT_UART_100; > + lasat_serial_res[1].end = LASATINT_UART_100; > + lasat_serial_res[1].flags = IORESOURCE_IRQ; > + > + lasat_serial8250_port[0].mapbase = LASAT_UART_REGS_BASE_100; > + lasat_serial8250_port[0].uartclk = LASAT_BASE_BAUD_100 * 16; > + lasat_serial8250_port[0].regshift = LASAT_UART_REGS_SHIFT_100; > + lasat_serial8250_port[0].irq = LASATINT_UART_100; > + } else { > + lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_200); > + lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_200 * 8 - 1; > + lasat_serial_res[0].flags = IORESOURCE_MEM; > + lasat_serial_res[1].start = LASATINT_UART_200; > + lasat_serial_res[1].end = LASATINT_UART_200; > + lasat_serial_res[1].flags = IORESOURCE_IRQ; > + > + lasat_serial8250_port[0].mapbase = LASAT_UART_REGS_BASE_200; > + lasat_serial8250_port[0].uartclk = LASAT_BASE_BAUD_200 * 16; > + lasat_serial8250_port[0].regshift = LASAT_UART_REGS_SHIFT_200; > + lasat_serial8250_port[0].irq = LASATINT_UART_200; > + } > + > + pdev->id = PLAT8250_DEV_PLATFORM; > + pdev->dev.platform_data = lasat_serial8250_port; > + > + retval = platform_device_add_resources(pdev, lasat_serial_res, ARRAY_SIZE(lasat_serial_res)); > + if (retval) > + goto err_free_device; > + > + retval = platform_device_add(pdev); > + if (retval) > + goto err_free_device; > + > + return 0; > + > +err_free_device: > + platform_device_put(pdev); > + > + return retval; > +} > +device_initcall(lasat_uart_add); > diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c > new file mode 100644 > index 0000000..6eeb0ce > --- /dev/null > +++ b/arch/mips/lasat/setup.c > @@ -0,0 +1,150 @@ > +/* > + * Carsten Langgaard, carstenl@xxxxxxxx > + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. > + * > + * Thomas Horsten <thh@xxxxxxxxx> > + * Copyright (C) 2000 LASAT Networks A/S. > + * > + * Brian Murphy <brian@xxxxxxxxx> > + * > + * This program is free software; you can distribute it and/or modify it > + * under the terms of the GNU General Public License (Version 2) as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * Lasat specific setup. > + */ > +#include <linux/init.h> > +#include <linux/sched.h> > +#include <linux/pci.h> > +#include <linux/interrupt.h> > +#include <linux/tty.h> > + > +#include <asm/time.h> > +#include <asm/cpu.h> > +#include <asm/bootinfo.h> > +#include <asm/irq.h> > +#include <asm/lasat/lasat.h> > +#include <asm/lasat/serial.h> > + > +#ifdef CONFIG_PICVUE > +#include <linux/notifier.h> > +#endif > + > +#include "ds1603.h" > +#include <asm/lasat/ds1603.h> > +#include <asm/lasat/picvue.h> > +#include <asm/lasat/eeprom.h> > + > +#include "prom.h" > + > +int lasat_command_line = 0; > +void lasatint_init(void); > + > +extern void lasat_reboot_setup(void); > +extern void pcisetup(void); > +extern void edhac_init(void *, void *, void *); > +extern void addrflt_init(void); > + > +struct lasat_misc lasat_misc_info[N_MACHTYPES] = { > + {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2}, > + {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6} > +}; > + > +struct lasat_misc *lasat_misc = NULL; > + > +#ifdef CONFIG_DS1603 > +static struct ds_defs ds_defs[N_MACHTYPES] = { > + { (void *)DS1603_REG_100, (void *)DS1603_REG_100, > + DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100, > + DS1603_DATA_SHIFT_100, 0, 0 }, > + { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200, > + DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200, > + DS1603_DATA_READ_SHIFT_200, 1, 2000 } > +}; > +#endif > + > +#ifdef CONFIG_PICVUE > +#include "picvue.h" > +static struct pvc_defs pvc_defs[N_MACHTYPES] = { > + { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100, > + PVC_E_100, PVC_RW_100, PVC_RS_100 }, > + { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200, > + PVC_E_200, PVC_RW_200, PVC_RS_200 } > +}; > +#endif > + > +static int lasat_panic_display(struct notifier_block *this, > + unsigned long event, void *ptr) > +{ > +#ifdef CONFIG_PICVUE > + unsigned char *string = ptr; > + if (string == NULL) > + string = "Kernel Panic"; > + pvc_dump_string(string); > +#endif > + return NOTIFY_DONE; > +} > + > +static int lasat_panic_prom_monitor(struct notifier_block *this, > + unsigned long event, void *ptr) > +{ > + prom_monitor(); > + return NOTIFY_DONE; > +} > + > +static struct notifier_block lasat_panic_block[] = > +{ > + { lasat_panic_display, NULL, INT_MAX }, > + { lasat_panic_prom_monitor, NULL, INT_MIN } > +}; > + > +static void lasat_time_init(void) > +{ > + mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2; > +} > + > +void __init plat_timer_setup(struct irqaction *irq) > +{ > + change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); > +} > + > +void __init plat_mem_setup(void) > +{ > + int i; > + lasat_misc = &lasat_misc_info[mips_machtype]; > +#ifdef CONFIG_PICVUE > + picvue = &pvc_defs[mips_machtype]; > +#endif > + > + /* Set up panic notifier */ > + for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) Changed this place and many others to use ARRAY_SIZE(). > + atomic_notifier_chain_register(&panic_notifier_list, > + &lasat_panic_block[i]); > + > + lasat_reboot_setup(); > + > + board_time_init = lasat_time_init; > + > +#ifdef CONFIG_DS1603 > + ds1603 = &ds_defs[mips_machtype]; > + rtc_mips_get_time = ds1603_read; > + rtc_mips_set_time = ds1603_set; > +#endif > + > +#ifdef DYNAMIC_SERIAL_INIT > + serial_init(); > +#endif Neither DYNAMIC_SERIAL_INIT nor are defined anywhere, so I deleted this. > + /* Switch from prom exception handler to normal mode */ > + change_c0_status(ST0_BEV,0); This already happens in traps.c and a clear_c0_status(ST0_BEV) would actually be a bit more readable and less code. > + > + pr_info("Lasat specific initialization complete\n"); > +} > diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c > new file mode 100644 > index 0000000..699ab18 > --- /dev/null > +++ b/arch/mips/lasat/sysctl.c > @@ -0,0 +1,441 @@ > +/* > + * Thomas Horsten <thh@xxxxxxxxx> > + * Copyright (C) 2000 LASAT Networks A/S. > + * > + * This program is free software; you can distribute it and/or modify it > + * under the terms of the GNU General Public License (Version 2) as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * Routines specific to the LASAT boards > + */ > +#include <linux/types.h> > +#include <asm/lasat/lasat.h> > + > +#include <linux/module.h> > +#include <linux/sysctl.h> > +#include <linux/stddef.h> > +#include <linux/init.h> > +#include <linux/fs.h> > +#include <linux/ctype.h> > +#include <linux/string.h> > +#include <linux/net.h> > +#include <linux/inet.h> > +#include <linux/mutex.h> > +#include <asm/uaccess.h> This should use <linux/uaccess.h> like all cases where a header file in include/linux exists which includes the include/asm/ file of the same name. > + > +#include "sysctl.h" > +#include "ds1603.h" > + > +static DEFINE_MUTEX(lasat_info_mutex); > + > +/* Strategy function to write EEPROM after changing string entry */ > +int sysctl_lasatstring(ctl_table *table, int *name, int nlen, > + void *oldval, size_t *oldlenp, > + void *newval, size_t newlen) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + r = sysctl_string(table, name, > + nlen, oldval, oldlenp, newval, newlen); > + if (r < 0) { > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + if (newval && newlen) { > + lasat_write_eeprom_info(); > + } > + mutex_unlock(&lasat_info_mutex); > + return 1; > +} > + > + > +/* And the same for proc */ > +int proc_dolasatstring(ctl_table *table, int write, struct file *filp, > + void *buffer, size_t *lenp, loff_t *ppos) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + r = proc_dostring(table, write, filp, buffer, lenp, ppos); > + if ( (!write) || r) { ^ No space here. > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + lasat_write_eeprom_info(); > + mutex_unlock(&lasat_info_mutex); > + return 0; > +} > + > +/* proc function to write EEPROM after changing int entry */ > +int proc_dolasatint(ctl_table *table, int write, struct file *filp, > + void *buffer, size_t *lenp, loff_t *ppos) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + r = proc_dointvec(table, write, filp, buffer, lenp, ppos); > + if ( (!write) || r) { ^ No space here. > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + lasat_write_eeprom_info(); > + mutex_unlock(&lasat_info_mutex); > + return 0; > +} > + > +static int rtctmp; > + > +#ifdef CONFIG_DS1603 > +/* proc function to read/write RealTime Clock */ > +int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, > + void *buffer, size_t *lenp, loff_t *ppos) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + if (!write) { > + rtctmp = ds1603_read(); > + /* check for time < 0 and set to 0 */ > + if (rtctmp < 0) > + rtctmp = 0; > + } > + r = proc_dointvec(table, write, filp, buffer, lenp, ppos); > + if ( (!write) || r) { > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + ds1603_set(rtctmp); > + mutex_unlock(&lasat_info_mutex); > + return 0; > +} > +#endif > + > +/* Sysctl for setting the IP addresses */ > +int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, > + void *oldval, size_t *oldlenp, > + void *newval, size_t newlen) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); > + if (r < 0) { > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + if (newval && newlen) { > + lasat_write_eeprom_info(); > + } > + mutex_unlock(&lasat_info_mutex); > + return 1; > +} > + > +#ifdef CONFIG_DS1603 > +/* Same for RTC */ > +int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, > + void *oldval, size_t *oldlenp, > + void *newval, size_t newlen) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + rtctmp = ds1603_read(); > + if (rtctmp < 0) > + rtctmp = 0; > + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); > + if (r < 0) { > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + if (newval && newlen) { > + ds1603_set(rtctmp); > + } > + mutex_unlock(&lasat_info_mutex); > + return 1; > +} > +#endif > + > +#ifdef CONFIG_INET > +static char lasat_bcastaddr[16]; > + > +void update_bcastaddr(void) > +{ > + unsigned int ip; > + > + ip = (lasat_board_info.li_eeprom_info.ipaddr & > + lasat_board_info.li_eeprom_info.netmask) | > + ~lasat_board_info.li_eeprom_info.netmask; > + > + sprintf(lasat_bcastaddr, "%d.%d.%d.%d", > + (ip ) & 0xff, > + (ip >> 8) & 0xff, > + (ip >> 16) & 0xff, > + (ip >> 24) & 0xff); > +} > + > +static char proc_lasat_ipbuf[32]; > +/* Parsing of IP address */ > +int proc_lasat_ip(ctl_table *table, int write, struct file *filp, > + void *buffer, size_t *lenp, loff_t *ppos) > +{ > + int len; > + unsigned int ip; > + char *p, c; > + > + if (!table->data || !table->maxlen || !*lenp || > + (*ppos && !write)) { > + *lenp = 0; > + return 0; > + } > + > + mutex_lock(&lasat_info_mutex); > + if (write) { > + len = 0; > + p = buffer; > + while (len < *lenp) { > + if(get_user(c, p++)) { > + mutex_unlock(&lasat_info_mutex); > + return -EFAULT; > + } > + if (c == 0 || c == '\n') > + break; > + len++; > + } > + if (len >= sizeof(proc_lasat_ipbuf)-1) > + len = sizeof(proc_lasat_ipbuf) - 1; > + if (copy_from_user(proc_lasat_ipbuf, buffer, len)) > + { > + mutex_unlock(&lasat_info_mutex); > + return -EFAULT; > + } > + proc_lasat_ipbuf[len] = 0; > + *ppos += *lenp; > + /* Now see if we can convert it to a valid IP */ > + ip = in_aton(proc_lasat_ipbuf); > + *(unsigned int *)(table->data) = ip; > + lasat_write_eeprom_info(); > + } else { > + ip = *(unsigned int *)(table->data); > + sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", > + (ip ) & 0xff, > + (ip >> 8) & 0xff, > + (ip >> 16) & 0xff, > + (ip >> 24) & 0xff); > + len = strlen(proc_lasat_ipbuf); > + if (len > *lenp) > + len = *lenp; > + if (len) > + if(copy_to_user(buffer, proc_lasat_ipbuf, len)) { > + mutex_unlock(&lasat_info_mutex); > + return -EFAULT; > + } > + if (len < *lenp) { > + if(put_user('\n', ((char *) buffer) + len)) { > + mutex_unlock(&lasat_info_mutex); > + return -EFAULT; > + } > + len++; > + } > + *lenp = len; > + *ppos += len; > + } > + update_bcastaddr(); > + mutex_unlock(&lasat_info_mutex); > + return 0; > +} > +#endif /* defined(CONFIG_INET) */ > + > +static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, > + void *oldval, size_t *oldlenp, > + void *newval, size_t newlen) > +{ > + int r; > + > + mutex_lock(&lasat_info_mutex); > + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); > + if (r < 0) { > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + > + if (newval && newlen) > + { > + if (name && *name == LASAT_PRID) > + lasat_board_info.li_eeprom_info.prid = *(int*)newval; > + > + lasat_write_eeprom_info(); > + lasat_init_board_info(); > + } > + mutex_unlock(&lasat_info_mutex); > + > + return 0; > +} > + > +int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, > + void *buffer, size_t *lenp, loff_t *ppos) > +{ > + int r; > + mutex_lock(&lasat_info_mutex); > + r = proc_dointvec(table, write, filp, buffer, lenp, ppos); > + if ( (!write) || r) { > + mutex_unlock(&lasat_info_mutex); > + return r; > + } > + if (filp && filp->f_path.dentry) > + { > + if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) > + lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; > + if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) > + lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; > + } > + lasat_write_eeprom_info(); > + mutex_unlock(&lasat_info_mutex); > + return 0; > +} > + > +extern int lasat_boot_to_service; > + > +#ifdef CONFIG_SYSCTL > + > +static ctl_table lasat_table[] = { > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "cpu-hz", > + .data = &lasat_board_info.li_cpu_hz, > + .maxlen = sizeof(int), > + .mode = 0444, > + .proc_handler = &proc_dointvec, > + .strategy = &sysctl_intvec > + }, > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "bus-hz", > + .data = &lasat_board_info.li_bus_hz, > + .maxlen = sizeof(int), > + .mode = 0444, > + .proc_handler = &proc_dointvec, > + .strategy = &sysctl_intvec > + }, > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "bmid", > + .data = &lasat_board_info.li_bmid, > + .maxlen = sizeof(int), > + .mode = 0444, > + .proc_handler = &proc_dointvec, > + .strategy = &sysctl_intvec > + }, > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "prid", > + .data = &lasat_board_info.li_prid, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = &proc_lasat_eeprom_value, > + .strategy = &sysctl_lasat_eeprom_value > + }, > +#ifdef CONFIG_INET > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "ipaddr", > + .data = &lasat_board_info.li_eeprom_info.ipaddr, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = &proc_lasat_ip, > + .strategy = &sysctl_lasat_intvec > + }, > + { > + .ctl_name = LASAT_NETMASK, > + .procname = "netmask", > + .data = &lasat_board_info.li_eeprom_info.netmask, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = &proc_lasat_ip, > + .strategy = &sysctl_lasat_intvec > + }, > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "bcastaddr", > + .data = &lasat_bcastaddr, > + .maxlen = sizeof(lasat_bcastaddr), > + .mode = 0600, > + .proc_handler = &proc_dostring, > + .strategy = &sysctl_string > + }, > +#endif > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "passwd_hash", > + .data = &lasat_board_info.li_eeprom_info.passwd_hash, > + .maxlen = sizeof(lasat_board_info.li_eeprom_info.passwd_hash), > + .mode = 0600, > + .proc_handler = &proc_dolasatstring, > + .strategy = &sysctl_lasatstring > + }, > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "boot-service", > + .data = &lasat_boot_to_service, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = &proc_dointvec, > + .strategy = &sysctl_intvec > + }, > +#ifdef CONFIG_DS1603 > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "rtc", > + .data = &rtctmp, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = &proc_dolasatrtc, > + .strategy = &sysctl_lasat_rtc > + }, > +#endif > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "namestr", > + .data = &lasat_board_info.li_namestr, > + .maxlen = sizeof(lasat_board_info.li_namestr), > + .mode = 0444, > + .proc_handler = &proc_dostring, > + .strategy = &sysctl_string > + }, > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "typestr", > + .data = &lasat_board_info.li_typestr, > + .maxlen = sizeof(lasat_board_info.li_typestr), > + .mode = 0444, > + .proc_handler = &proc_dostring, > + .strategy = &sysctl_string > + }, > + {} > +}; > + > +static ctl_table lasat_root_table[] = { > + { > + .ctl_name = CTL_UNNUMBERED, > + .procname = "lasat", > + .mode = 0555, > + .child = lasat_table > + }, > + {} > +}; > + > +static int __init lasat_register_sysctl(void) > +{ > + struct ctl_table_header *lasat_table_header; > + > + lasat_table_header = > + register_sysctl_table(lasat_root_table); > + > + return 0; > +} > + > +__initcall(lasat_register_sysctl); > +#endif /* CONFIG_SYSCTL */ > diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h > new file mode 100644 > index 0000000..4d139d2 > --- /dev/null > +++ b/arch/mips/lasat/sysctl.h > @@ -0,0 +1,24 @@ > +/* > + * LASAT sysctl values > + */ > + > +#ifndef _LASAT_SYSCTL_H > +#define _LASAT_SYSCTL_H > + > +/* /proc/sys/lasat */ > +enum { > + LASAT_CPU_HZ=1, > + LASAT_BUS_HZ, > + LASAT_MODEL, > + LASAT_PRID, > + LASAT_IPADDR, > + LASAT_NETMASK, > + LASAT_BCAST, > + LASAT_PASSWORD, > + LASAT_SBOOT, > + LASAT_RTC, > + LASAT_NAMESTR, > + LASAT_TYPESTR, > +}; > + > +#endif /* _LASAT_SYSCTL_H */ > diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile > index 4ee6800..ed0c076 100644 > --- a/arch/mips/pci/Makefile > +++ b/arch/mips/pci/Makefile > @@ -10,6 +10,7 @@ obj-y += pci.o > obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o > obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o > obj-$(CONFIG_MIPS_MSC) += ops-msc.o > +obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o > obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o > obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o > obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o > @@ -19,6 +20,7 @@ obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o > # These are still pretty much in the old state, watch, go blind. > # > obj-$(CONFIG_BASLER_EXCITE) += ops-titan.o pci-excite.o fixup-excite.o > +obj-$(CONFIG_LASAT) += pci-lasat.o > obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o > obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o > obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o > diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c > new file mode 100644 > index 0000000..a8d38dc > --- /dev/null > +++ b/arch/mips/pci/ops-nile4.c > @@ -0,0 +1,147 @@ > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/pci.h> > +#include <asm/bootinfo.h> > + > +#include <asm/lasat/lasat.h> > +#include <asm/gt64120.h> > +#include <asm/nile4.h> > + > +#define PCI_ACCESS_READ 0 > +#define PCI_ACCESS_WRITE 1 > + > +#define LO(reg) (reg / 4) > +#define HI(reg) (reg / 4 + 1) > + > +volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; > + > +static DEFINE_SPINLOCK(nile4_pci_lock); > + > +static int nile4_pcibios_config_access(unsigned char access_type, > + struct pci_bus *bus, unsigned int devfn, int where, u32 * val) > +{ > + unsigned char busnum = bus->number; > + u32 adr, mask, err; > + > + if ((busnum == 0) && (PCI_SLOT(devfn) > 8)) > + /* The addressing scheme chosen leaves room for just > + * 8 devices on the first busnum (besides the PCI > + * controller itself) */ > + return PCIBIOS_DEVICE_NOT_FOUND; > + > + if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) { > + /* Access controller registers directly */ > + if (access_type == PCI_ACCESS_WRITE) { > + vrc_pciregs[(0x200 + where) >> 2] = *val; > + } else { > + *val = vrc_pciregs[(0x200 + where) >> 2]; > + } > + return PCIBIOS_SUCCESSFUL; > + } > + > + /* Temporarily map PCI Window 1 to config space */ > + mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; > + vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0); > + > + /* Clear PCI Error register. This also clears the Error Type > + * bits in the Control register */ > + vrc_pciregs[LO(NILE4_PCIERR)] = 0; > + vrc_pciregs[HI(NILE4_PCIERR)] = 0; > + > + /* Setup address */ > + if (busnum == 0) > + adr = > + KSEG1ADDR(PCI_WINDOW1) + > + ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8) > + | (where & ~3)); > + else > + adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) | > + (where & ~3); > + > + if (access_type == PCI_ACCESS_WRITE) > + *(u32 *) adr = *val; > + else > + *val = *(u32 *) adr; > + > + /* Check for master or target abort */ > + err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; > + > + /* Restore PCI Window 1 */ > + vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; > + > + if (err) > + return PCIBIOS_DEVICE_NOT_FOUND; > + > + return PCIBIOS_SUCCESSFUL; > +} > + > +static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, > + int where, int size, u32 * val) > +{ > + unsigned long flags; > + u32 data = 0; > + int err; > + > + if ((size == 2) && (where & 1)) > + return PCIBIOS_BAD_REGISTER_NUMBER; > + else if ((size == 4) && (where & 3)) > + return PCIBIOS_BAD_REGISTER_NUMBER; > + > + spin_lock_irqsave(&nile4_pci_lock, flags); > + err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, > + &data); > + spin_unlock_irqrestore(&nile4_pci_lock, flags); > + > + if (err) > + return err; > + > + if (size == 1) > + *val = (data >> ((where & 3) << 3)) & 0xff; > + else if (size == 2) > + *val = (data >> ((where & 3) << 3)) & 0xffff; > + else > + *val = data; > + > + return PCIBIOS_SUCCESSFUL; > +} > + > +static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, > + int where, int size, u32 val) > +{ > + unsigned long flags; > + u32 data = 0; > + int err; > + > + if ((size == 2) && (where & 1)) > + return PCIBIOS_BAD_REGISTER_NUMBER; > + else if ((size == 4) && (where & 3)) > + return PCIBIOS_BAD_REGISTER_NUMBER; > + > + spin_lock_irqsave(&nile4_pci_lock, flags); > + err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, > + &data); > + spin_unlock_irqrestore(&nile4_pci_lock, flags); > + > + if (err) > + return err; > + > + if (size == 1) > + data = (data & ~(0xff << ((where & 3) << 3))) | > + (val << ((where & 3) << 3)); > + else if (size == 2) > + data = (data & ~(0xffff << ((where & 3) << 3))) | > + (val << ((where & 3) << 3)); > + else > + data = val; > + > + if (nile4_pcibios_config_access > + (PCI_ACCESS_WRITE, bus, devfn, where, &data)) > + return -1; > + > + return PCIBIOS_SUCCESSFUL; > +} > + > +struct pci_ops nile4_pci_ops = { > + .read = nile4_pcibios_read, > + .write = nile4_pcibios_write, > +}; > diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c > new file mode 100644 > index 0000000..c5045ff > --- /dev/null > +++ b/arch/mips/pci/pci-lasat.c > @@ -0,0 +1,91 @@ > +/* > + * 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) 2000, 2001, 04 Keith M Wesolowski > + */ > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/pci.h> > +#include <linux/types.h> > +#include <asm/bootinfo.h> > + > +extern struct pci_ops nile4_pci_ops; > +extern struct pci_ops gt64xxx_pci0_ops; > +static struct resource lasat_pci_mem_resource = { > + .name = "LASAT PCI MEM", > + .start = 0x18000000, > + .end = 0x19ffffff, > + .flags = IORESOURCE_MEM, > +}; > + > +static struct resource lasat_pci_io_resource = { > + .name = "LASAT PCI IO", > + .start = 0x1a000000, > + .end = 0x1bffffff, > + .flags = IORESOURCE_IO, > +}; > + > +static struct pci_controller lasat_pci_controller = { > + .mem_resource = &lasat_pci_mem_resource, > + .io_resource = &lasat_pci_io_resource, > +}; > + > +static int __init lasat_pci_setup(void) > +{ > + printk("PCI: starting\n"); > + > + switch (mips_machtype) { > + case MACH_LASAT_100: > + lasat_pci_controller.pci_ops = >64xxx_pci0_ops; > + break; > + case MACH_LASAT_200: > + lasat_pci_controller.pci_ops = &nile4_pci_ops; > + break; > + default: > + panic("pcibios_init: mips_machtype incorrect"); > + } > + > + register_pci_controller(&lasat_pci_controller); > + > + return 0; > +} > + > +arch_initcall(lasat_pci_setup); > + > +#define LASATINT_ETH1 0 > +#define LASATINT_ETH0 1 > +#define LASATINT_HDC 2 > +#define LASATINT_COMP 3 > +#define LASATINT_HDLC 4 > +#define LASATINT_PCIA 5 > +#define LASATINT_PCIB 6 > +#define LASATINT_PCIC 7 > +#define LASATINT_PCID 8 > + > +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) > +{ > + switch (slot) { > + case 1: > + case 2: > + case 3: > + return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4); > + case 4: > + return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */ > + case 5: > + return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */ > + case 6: > + return LASATINT_HDC; /* IDE controller */ > + default: > + return 0xff; /* Illegal */ > + } > + > + return -1; > +} > + > +/* Do platform specific device initialization at pci_enable_device() time */ > +int pcibios_plat_dev_init(struct pci_dev *dev) > +{ > + return 0; > +} > diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig > index cc6c734..829723e 100644 > --- a/drivers/mtd/maps/Kconfig > +++ b/drivers/mtd/maps/Kconfig > @@ -258,6 +258,12 @@ config MTD_TSUNAMI > help > Support for the flash chip on Tsunami TIG bus. > > +config MTD_LASAT > + tristate "LASAT flash device" > + depends on LASAT && MTD_CFI > + help > + Support for the flash chips on the Lasat 100 and 200 boards. > + > config MTD_NETtel > tristate "CFI flash device on SnapGear/SecureEdge" > depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE > diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile > index 970b189..3acbb5d 100644 > --- a/drivers/mtd/maps/Makefile > +++ b/drivers/mtd/maps/Makefile > @@ -47,6 +47,7 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o > obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o > obj-$(CONFIG_MTD_PCI) += pci.o > obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o > +obj-$(CONFIG_MTD_LASAT) += lasat.o > obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o > obj-$(CONFIG_MTD_EDB7312) += edb7312.o > obj-$(CONFIG_MTD_IMPA7) += impa7.o > diff --git a/drivers/mtd/maps/lasat.c b/drivers/mtd/maps/lasat.c > new file mode 100644 > index 0000000..e343763 > --- /dev/null > +++ b/drivers/mtd/maps/lasat.c > @@ -0,0 +1,103 @@ > +/* > + * Flash device on Lasat 100 and 200 boards > + * > + * (C) 2002 Brian Murphy <brian@xxxxxxxxx> > + * > + * 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. > + * > + * $Id: lasat.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $ > + * > + */ > + > +#include <linux/module.h> > +#include <linux/types.h> > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <asm/io.h> > +#include <linux/mtd/mtd.h> > +#include <linux/mtd/map.h> > +#include <linux/mtd/partitions.h> > +#include <asm/lasat/lasat.h> > + > +static struct mtd_info *lasat_mtd; > + > +static struct mtd_partition partition_info[LASAT_MTD_LAST]; > +static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; > + > +static void lasat_set_vpp(struct map_info *map, int vpp) > +{ > + if (vpp) > + *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; > + else > + *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit); > +} > + > +static struct map_info lasat_map = { > + .name = "LASAT flash", > + .bankwidth = 4, > + .set_vpp = lasat_set_vpp > +}; > + > +static int __init init_lasat(void) > +{ > + int i; > + /* since we use AMD chips and set_vpp is not implimented > + * for these (yet) we still have to permanently enable flash write */ > + printk(KERN_NOTICE "Unprotecting flash\n"); > + ENABLE_VPP((&lasat_map)); > + > + lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); > + lasat_map.virt = ioremap_nocache( > + lasat_map.phys, lasat_board_info.li_flash_size); > + lasat_map.size = lasat_board_info.li_flash_size; > + > + simple_map_init(&lasat_map); > + > + for (i=0; i < LASAT_MTD_LAST; i++) > + partition_info[i].name = lasat_mtd_partnames[i]; > + > + lasat_mtd = do_map_probe("cfi_probe", &lasat_map); > + > + if (!lasat_mtd) > + lasat_mtd = do_map_probe("jedec_probe", &lasat_map); > + > + if (lasat_mtd) { > + u32 size, offset = 0; > + > + lasat_mtd->owner = THIS_MODULE; > + > + for (i=0; i < LASAT_MTD_LAST; i++) { > + size = lasat_flash_partition_size(i); > + partition_info[i].size = size; > + partition_info[i].offset = offset; > + offset += size; > + } > + > + add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST ); > + return 0; > + } > + > + iounmap(lasat_map.virt); > + return -ENXIO; > +} > + > +static void __exit cleanup_lasat(void) > +{ > + if (lasat_mtd) { > + del_mtd_partitions(lasat_mtd); > + map_destroy(lasat_mtd); > + } > + if (lasat_map.virt) { > + iounmap(lasat_map.virt); > + lasat_map.virt = 0; > + } > +} > + > +module_init(init_lasat); > +module_exit(cleanup_lasat); > + > +MODULE_LICENSE("GPL"); > +MODULE_AUTHOR("Brian Murphy <brian@xxxxxxxxx>"); > +MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver"); > diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h > index c0f052b..1bb4bf6 100644 > --- a/include/asm-mips/bootinfo.h > +++ b/include/asm-mips/bootinfo.h > @@ -175,6 +175,13 @@ > #define MACH_HP_LASERJET 1 > > /* > + * Valid machtype for group LASAT > + */ > +#define MACH_GROUP_LASAT 21 > +#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ > +#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ > + > +/* > * Valid machtype for group TITAN > */ > #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ > diff --git a/include/asm-mips/lasat/ds1603.h b/include/asm-mips/lasat/ds1603.h > new file mode 100644 > index 0000000..edcd754 > --- /dev/null > +++ b/include/asm-mips/lasat/ds1603.h > @@ -0,0 +1,18 @@ > +#include <asm/addrspace.h> > + > +/* Lasat 100 */ > +#define DS1603_REG_100 (KSEG1ADDR(0x1c810000)) > +#define DS1603_RST_100 (1 << 2) > +#define DS1603_CLK_100 (1 << 0) > +#define DS1603_DATA_SHIFT_100 1 > +#define DS1603_DATA_100 (1 << DS1603_DATA_SHIFT_100) > + > +/* Lasat 200 */ > +#define DS1603_REG_200 (KSEG1ADDR(0x11000000)) > +#define DS1603_RST_200 (1 << 3) > +#define DS1603_CLK_200 (1 << 4) > +#define DS1603_DATA_200 (1 << 5) > + > +#define DS1603_DATA_REG_200 (DS1603_REG_200 + 0x10000) > +#define DS1603_DATA_READ_SHIFT_200 9 > +#define DS1603_DATA_READ_200 (1 << DS1603_DATA_READ_SHIFT_200) > diff --git a/include/asm-mips/lasat/eeprom.h b/include/asm-mips/lasat/eeprom.h > new file mode 100644 > index 0000000..7b53edd > --- /dev/null > +++ b/include/asm-mips/lasat/eeprom.h > @@ -0,0 +1,17 @@ > +#include <asm/addrspace.h> > + > +/* lasat 100 */ > +#define AT93C_REG_100 KSEG1ADDR(0x1c810000) > +#define AT93C_RDATA_REG_100 AT93C_REG_100 > +#define AT93C_RDATA_SHIFT_100 4 > +#define AT93C_WDATA_SHIFT_100 4 > +#define AT93C_CS_M_100 ( 1 << 5 ) > +#define AT93C_CLK_M_100 ( 1 << 3 ) > + > +/* lasat 200 */ > +#define AT93C_REG_200 KSEG1ADDR(0x11000000) > +#define AT93C_RDATA_REG_200 (AT93C_REG_200+0x10000) > +#define AT93C_RDATA_SHIFT_200 8 > +#define AT93C_WDATA_SHIFT_200 2 > +#define AT93C_CS_M_200 ( 1 << 0 ) > +#define AT93C_CLK_M_200 ( 1 << 1 ) > diff --git a/include/asm-mips/lasat/head.h b/include/asm-mips/lasat/head.h > new file mode 100644 > index 0000000..f5589f3 > --- /dev/null > +++ b/include/asm-mips/lasat/head.h > @@ -0,0 +1,22 @@ > +/* > + * Image header stuff > + */ > +#ifndef _HEAD_H > +#define _HEAD_H > + > +#define LASAT_K_MAGIC0_VAL 0xfedeabba > +#define LASAT_K_MAGIC1_VAL 0x00bedead > + > +#ifndef _LANGUAGE_ASSEMBLY > +#include <linux/types.h> > +struct bootloader_header { > + u32 magic[2]; > + u32 version; > + u32 image_start; > + u32 image_size; > + u32 kernel_start; > + u32 kernel_entry; > +}; > +#endif > + > +#endif /* _HEAD_H */ > diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h > new file mode 100644 > index 0000000..42077e3 > --- /dev/null > +++ b/include/asm-mips/lasat/lasat.h > @@ -0,0 +1,253 @@ > +/* > + * lasat.h > + * > + * Thomas Horsten <thh@xxxxxxxxx> > + * Copyright (C) 2000 LASAT Networks A/S. > + * > + * This program is free software; you can distribute it and/or modify it > + * under the terms of the GNU General Public License (Version 2) as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * Configuration for LASAT boards, loads the appropriate include files. > + */ > +#ifndef _LASAT_H > +#define _LASAT_H > + > +#ifndef _LANGUAGE_ASSEMBLY > + > +extern struct lasat_misc { > + volatile u32 *reset_reg; > + volatile u32 *flash_wp_reg; > + u32 flash_wp_bit; > +} *lasat_misc; > + > +enum lasat_mtdparts { > + LASAT_MTD_BOOTLOADER, > + LASAT_MTD_SERVICE, > + LASAT_MTD_NORMAL, > + LASAT_MTD_CONFIG, > + LASAT_MTD_FS, > + LASAT_MTD_LAST > +}; > + > +/* > + * The format of the data record in the EEPROM. > + * See Documentation/LASAT/eeprom.txt for a detailed description > + * of the fields in this struct, and the LASAT Hardware Configuration > + * field specification for a detailed description of the config > + * field. > + */ > +#include <linux/types.h> > + > +#define LASAT_EEPROM_VERSION 7 > +struct lasat_eeprom_struct { > + unsigned int version; > + unsigned int cfg[3]; > + unsigned char hwaddr[6]; > + unsigned char print_partno[12]; > + unsigned char term0; > + unsigned char print_serial[14]; > + unsigned char term1; > + unsigned char prod_partno[12]; > + unsigned char term2; > + unsigned char prod_serial[14]; > + unsigned char term3; > + unsigned char passwd_hash[16]; > + unsigned char pwdnull; > + unsigned char vendid; > + unsigned char ts_ref; > + unsigned char ts_signoff; > + unsigned char reserved[11]; > + unsigned char debugaccess; > + unsigned short prid; > + unsigned int serviceflag; > + unsigned int ipaddr; > + unsigned int netmask; > + unsigned int crc32; > +}; > + > +struct lasat_eeprom_struct_pre7 { > + unsigned int version; > + unsigned int flags[3]; > + unsigned char hwaddr0[6]; > + unsigned char hwaddr1[6]; > + unsigned char print_partno[9]; > + unsigned char term0; > + unsigned char print_serial[14]; > + unsigned char term1; > + unsigned char prod_partno[9]; > + unsigned char term2; > + unsigned char prod_serial[14]; > + unsigned char term3; > + unsigned char passwd_hash[24]; > + unsigned char pwdnull; > + unsigned char vendor; > + unsigned char ts_ref; > + unsigned char ts_signoff; > + unsigned char reserved[6]; > + unsigned int writecount; > + unsigned int ipaddr; > + unsigned int netmask; > + unsigned int crc32; > +}; > + > +/* Configuration descriptor encoding - see the doc for details */ > + > +#define LASAT_W0_DSCTYPE(v) ( ( (v) ) & 0xf ) > +#define LASAT_W0_BMID(v) ( ( (v) >> 0x04 ) & 0xf ) > +#define LASAT_W0_CPUTYPE(v) ( ( (v) >> 0x08 ) & 0xf ) > +#define LASAT_W0_BUSSPEED(v) ( ( (v) >> 0x0c ) & 0xf ) > +#define LASAT_W0_CPUCLK(v) ( ( (v) >> 0x10 ) & 0xf ) > +#define LASAT_W0_SDRAMBANKSZ(v) ( ( (v) >> 0x14 ) & 0xf ) > +#define LASAT_W0_SDRAMBANKS(v) ( ( (v) >> 0x18 ) & 0xf ) > +#define LASAT_W0_L2CACHE(v) ( ( (v) >> 0x1c ) & 0xf ) > + > +#define LASAT_W1_EDHAC(v) ( ( (v) ) & 0xf ) > +#define LASAT_W1_HIFN(v) ( ( (v) >> 0x04 ) & 0x1 ) > +#define LASAT_W1_ISDN(v) ( ( (v) >> 0x05 ) & 0x1 ) > +#define LASAT_W1_IDE(v) ( ( (v) >> 0x06 ) & 0x1 ) > +#define LASAT_W1_HDLC(v) ( ( (v) >> 0x07 ) & 0x1 ) > +#define LASAT_W1_USVERSION(v) ( ( (v) >> 0x08 ) & 0x1 ) > +#define LASAT_W1_4MACS(v) ( ( (v) >> 0x09 ) & 0x1 ) > +#define LASAT_W1_EXTSERIAL(v) ( ( (v) >> 0x0a ) & 0x1 ) > +#define LASAT_W1_FLASHSIZE(v) ( ( (v) >> 0x0c ) & 0xf ) > +#define LASAT_W1_PCISLOTS(v) ( ( (v) >> 0x10 ) & 0xf ) > +#define LASAT_W1_PCI1OPT(v) ( ( (v) >> 0x14 ) & 0xf ) > +#define LASAT_W1_PCI2OPT(v) ( ( (v) >> 0x18 ) & 0xf ) > +#define LASAT_W1_PCI3OPT(v) ( ( (v) >> 0x1c ) & 0xf ) > + > +/* Routines specific to LASAT boards */ > + > +#define LASAT_BMID_MASQUERADE2 0 > +#define LASAT_BMID_MASQUERADEPRO 1 > +#define LASAT_BMID_SAFEPIPE25 2 > +#define LASAT_BMID_SAFEPIPE50 3 > +#define LASAT_BMID_SAFEPIPE100 4 > +#define LASAT_BMID_SAFEPIPE5000 5 > +#define LASAT_BMID_SAFEPIPE7000 6 > +#define LASAT_BMID_SAFEPIPE1000 7 > +//#define LASAT_BMID_SAFEPIPE30 7 > +//#define LASAT_BMID_SAFEPIPE5100 8 > +//#define LASAT_BMID_SAFEPIPE7100 9 > +#define LASAT_BMID_UNKNOWN 0xf > +#define LASAT_MAX_BMID_NAMES 9 // no larger than 15! > + > +#define LASAT_HAS_EDHAC ( 1 << 0 ) > +#define LASAT_EDHAC_FAST ( 1 << 1 ) > +#define LASAT_HAS_EADI ( 1 << 2 ) > +#define LASAT_HAS_HIFN ( 1 << 3 ) > +#define LASAT_HAS_ISDN ( 1 << 4 ) > +#define LASAT_HAS_LEASEDLINE_IF ( 1 << 5 ) > +#define LASAT_HAS_HDC ( 1 << 6 ) > + > +#define LASAT_PRID_MASQUERADE2 0 > +#define LASAT_PRID_MASQUERADEPRO 1 > +#define LASAT_PRID_SAFEPIPE25 2 > +#define LASAT_PRID_SAFEPIPE50 3 > +#define LASAT_PRID_SAFEPIPE100 4 > +#define LASAT_PRID_SAFEPIPE5000 5 > +#define LASAT_PRID_SAFEPIPE7000 6 > +#define LASAT_PRID_SAFEPIPE30 7 > +#define LASAT_PRID_SAFEPIPE5100 8 > +#define LASAT_PRID_SAFEPIPE7100 9 > + > +#define LASAT_PRID_SAFEPIPE1110 10 > +#define LASAT_PRID_SAFEPIPE3020 11 > +#define LASAT_PRID_SAFEPIPE3030 12 > +#define LASAT_PRID_SAFEPIPE5020 13 > +#define LASAT_PRID_SAFEPIPE5030 14 > +#define LASAT_PRID_SAFEPIPE1120 15 > +#define LASAT_PRID_SAFEPIPE1130 16 > +#define LASAT_PRID_SAFEPIPE6010 17 > +#define LASAT_PRID_SAFEPIPE6110 18 > +#define LASAT_PRID_SAFEPIPE6210 19 > +#define LASAT_PRID_SAFEPIPE1020 20 > +#define LASAT_PRID_SAFEPIPE1040 21 > +#define LASAT_PRID_SAFEPIPE1060 22 > + > +struct lasat_info { > + unsigned int li_cpu_hz; > + unsigned int li_bus_hz; > + unsigned int li_bmid; > + unsigned int li_memsize; > + unsigned int li_flash_size; > + unsigned int li_prid; > + unsigned char li_bmstr[16]; > + unsigned char li_namestr[32]; > + unsigned char li_typestr[16]; > + /* Info on the Flash layout */ > + unsigned int li_flash_base; > + unsigned long li_flashpart_base[LASAT_MTD_LAST]; > + unsigned long li_flashpart_size[LASAT_MTD_LAST]; > + struct lasat_eeprom_struct li_eeprom_info; > + unsigned int li_eeprom_upgrade_version; > + unsigned int li_debugaccess; > +}; > + > +extern struct lasat_info lasat_board_info; > + > +static inline unsigned long lasat_flash_partition_start(int partno) > +{ > + if (partno < 0 || partno >= LASAT_MTD_LAST) > + return 0; > + > + return lasat_board_info.li_flashpart_base[partno]; > +} > + > +static inline unsigned long lasat_flash_partition_size(int partno) > +{ > + if (partno < 0 || partno >= LASAT_MTD_LAST) > + return 0; > + > + return lasat_board_info.li_flashpart_size[partno]; > +} > + > +/* Called from setup() to initialize the global board_info struct */ > +extern int lasat_init_board_info(void); > + > +/* Write the modified EEPROM info struct */ > +extern void lasat_write_eeprom_info(void); > + > +#define N_MACHTYPES 2 > +/* for calibration of delays */ > + > +/* the lasat_ndelay function is necessary because it is used at an > + * early stage of the boot process where ndelay is not calibrated. > + * It is used for the bit-banging rtc and eeprom drivers */ > + > +#include <asm/delay.h> > +/* calculating with the slowest board with 100 MHz clock */ > +#define LASAT_100_DIVIDER 20 > +/* All 200's run at 250 MHz clock */ > +#define LASAT_200_DIVIDER 8 > + > +extern unsigned int lasat_ndelay_divider; > + > +static inline void lasat_ndelay(unsigned int ns) > +{ > + __delay(ns / lasat_ndelay_divider); > +} > + > +#endif /* !defined (_LANGUAGE_ASSEMBLY) */ > + > +#define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef > +#define LASAT_SERVICEMODE_MAGIC_2 0xfedeabba > + > +/* Lasat 100 boards */ > +#define LASAT_GT_BASE (KSEG1ADDR(0x14000000)) > + > +/* Lasat 200 boards */ > +#define Vrc5074_PHYS_BASE 0x1fa00000 > +#define Vrc5074_BASE (KSEG1ADDR(Vrc5074_PHYS_BASE)) > +#define PCI_WINDOW1 0x1a000000 > + > +#endif /* _LASAT_H */ > diff --git a/include/asm-mips/lasat/lasatint.h b/include/asm-mips/lasat/lasatint.h > new file mode 100644 > index 0000000..065474f > --- /dev/null > +++ b/include/asm-mips/lasat/lasatint.h > @@ -0,0 +1,12 @@ > +#define LASATINT_END 16 > + > +/* lasat 100 */ > +#define LASAT_INT_STATUS_REG_100 (KSEG1ADDR(0x1c880000)) > +#define LASAT_INT_MASK_REG_100 (KSEG1ADDR(0x1c890000)) > +#define LASATINT_MASK_SHIFT_100 0 > + > +/* lasat 200 */ > +#define LASAT_INT_STATUS_REG_200 (KSEG1ADDR(0x1104003c)) > +#define LASAT_INT_MASK_REG_200 (KSEG1ADDR(0x1104003c)) > +#define LASATINT_MASK_SHIFT_200 16 > + > diff --git a/include/asm-mips/lasat/picvue.h b/include/asm-mips/lasat/picvue.h > new file mode 100644 > index 0000000..42a492e > --- /dev/null > +++ b/include/asm-mips/lasat/picvue.h > @@ -0,0 +1,15 @@ > +/* Lasat 100 */ > +#define PVC_REG_100 KSEG1ADDR(0x1c820000) > +#define PVC_DATA_SHIFT_100 0 > +#define PVC_DATA_M_100 0xFF > +#define PVC_E_100 (1 << 8) > +#define PVC_RW_100 (1 << 9) > +#define PVC_RS_100 (1 << 10) > + > +/* Lasat 200 */ > +#define PVC_REG_200 KSEG1ADDR(0x11000000) > +#define PVC_DATA_SHIFT_200 24 > +#define PVC_DATA_M_200 (0xFF << PVC_DATA_SHIFT_200) > +#define PVC_E_200 (1 << 16) > +#define PVC_RW_200 (1 << 17) > +#define PVC_RS_200 (1 << 18) > diff --git a/include/asm-mips/lasat/serial.h b/include/asm-mips/lasat/serial.h > new file mode 100644 > index 0000000..9e88c76 > --- /dev/null > +++ b/include/asm-mips/lasat/serial.h > @@ -0,0 +1,13 @@ > +#include <asm/lasat/lasat.h> > + > +/* Lasat 100 boards serial configuration */ > +#define LASAT_BASE_BAUD_100 ( 7372800 / 16 ) > +#define LASAT_UART_REGS_BASE_100 0x1c8b0000 > +#define LASAT_UART_REGS_SHIFT_100 2 > +#define LASATINT_UART_100 8 > + > +/* * LASAT 200 boards serial configuration */ > +#define LASAT_BASE_BAUD_200 (100000000 / 16 / 12) > +#define LASAT_UART_REGS_BASE_200 (Vrc5074_PHYS_BASE + 0x0300) > +#define LASAT_UART_REGS_SHIFT_200 3 > +#define LASATINT_UART_200 13 > diff --git a/include/asm-mips/mach-lasat/mach-gt64120.h b/include/asm-mips/mach-lasat/mach-gt64120.h > new file mode 100644 > index 0000000..1a9ad45 > --- /dev/null > +++ b/include/asm-mips/mach-lasat/mach-gt64120.h > @@ -0,0 +1,27 @@ > +/* > + * This is a direct copy of the ev96100.h file, with a global > + * search and replace. The numbers are the same. > + * > + * The reason I'm duplicating this is so that the 64120/96100 > + * defines won't be confusing in the source code. > + */ > +#ifndef _ASM_GT64120_LASAT_GT64120_DEP_H > +#define _ASM_GT64120_LASAT_GT64120_DEP_H > + > +/* > + * GT64120 config space base address on Lasat 100 > + */ > +#define GT64120_BASE (KSEG1ADDR(0x14000000)) > + > +/* > + * PCI Bus allocation > + * > + * (Guessing ...) > + */ > +#define GT_PCI_MEM_BASE 0x12000000UL > +#define GT_PCI_MEM_SIZE 0x02000000UL > +#define GT_PCI_IO_BASE 0x10000000UL > +#define GT_PCI_IO_SIZE 0x02000000UL > +#define GT_ISA_IO_BASE PCI_IO_BASE > + > +#endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */ > diff --git a/include/asm-mips/nile4.h b/include/asm-mips/nile4.h > new file mode 100644 > index 0000000..c3ca959 > --- /dev/null > +++ b/include/asm-mips/nile4.h > @@ -0,0 +1,310 @@ > +/* > + * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions > + * > + * Copyright (C) 2000 Geert Uytterhoeven <geert@xxxxxxxxxxx> > + * Sony Software Development Center Europe (SDCE), Brussels > + * > + * This file is based on the following documentation: > + * > + * NEC Vrc 5074 System Controller Data Sheet, June 1998 > + */ > + > +#ifndef _ASM_NILE4_H > +#define _ASM_NILE4_H > + > +#define NILE4_BASE 0xbfa00000 > +#define NILE4_SIZE 0x00200000 /* 2 MB */ > + > + > + /* > + * Physical Device Address Registers (PDARs) > + */ > + > +#define NILE4_SDRAM0 0x0000 /* SDRAM Bank 0 [R/W] */ > +#define NILE4_SDRAM1 0x0008 /* SDRAM Bank 1 [R/W] */ > +#define NILE4_DCS2 0x0010 /* Device Chip-Select 2 [R/W] */ > +#define NILE4_DCS3 0x0018 /* Device Chip-Select 3 [R/W] */ > +#define NILE4_DCS4 0x0020 /* Device Chip-Select 4 [R/W] */ > +#define NILE4_DCS5 0x0028 /* Device Chip-Select 5 [R/W] */ > +#define NILE4_DCS6 0x0030 /* Device Chip-Select 6 [R/W] */ > +#define NILE4_DCS7 0x0038 /* Device Chip-Select 7 [R/W] */ > +#define NILE4_DCS8 0x0040 /* Device Chip-Select 8 [R/W] */ > +#define NILE4_PCIW0 0x0060 /* PCI Address Window 0 [R/W] */ > +#define NILE4_PCIW1 0x0068 /* PCI Address Window 1 [R/W] */ > +#define NILE4_INTCS 0x0070 /* Controller Internal Registers and Devices */ > + /* [R/W] */ > +#define NILE4_BOOTCS 0x0078 /* Boot ROM Chip-Select [R/W] */ > + > + > + /* > + * CPU Interface Registers > + */ > + > +#define NILE4_CPUSTAT 0x0080 /* CPU Status [R/W] */ > +#define NILE4_INTCTRL 0x0088 /* Interrupt Control [R/W] */ > +#define NILE4_INTSTAT0 0x0090 /* Interrupt Status 0 [R] */ > +#define NILE4_INTSTAT1 0x0098 /* Interrupt Status 1 and CPU Interrupt */ > + /* Enable [R/W] */ > +#define NILE4_INTCLR 0x00A0 /* Interrupt Clear [R/W] */ > +#define NILE4_INTPPES 0x00A8 /* PCI Interrupt Control [R/W] */ > + > + > + /* > + * Memory-Interface Registers > + */ > + > +#define NILE4_MEMCTRL 0x00C0 /* Memory Control */ > +#define NILE4_ACSTIME 0x00C8 /* Memory Access Timing [R/W] */ > +#define NILE4_CHKERR 0x00D0 /* Memory Check Error Status [R] */ > + > + > + /* > + * PCI-Bus Registers > + */ > + > +#define NILE4_PCICTRL 0x00E0 /* PCI Control [R/W] */ > +#define NILE4_PCIARB 0x00E8 /* PCI Arbiter [R/W] */ > +#define NILE4_PCIINIT0 0x00F0 /* PCI Master (Initiator) 0 [R/W] */ > +#define NILE4_PCIINIT1 0x00F8 /* PCI Master (Initiator) 1 [R/W] */ > +#define NILE4_PCIERR 0x00B8 /* PCI Error [R/W] */ > + > + > + /* > + * Local-Bus Registers > + */ > + > +#define NILE4_LCNFG 0x0100 /* Local Bus Configuration [R/W] */ > +#define NILE4_LCST2 0x0110 /* Local Bus Chip-Select Timing 2 [R/W] */ > +#define NILE4_LCST3 0x0118 /* Local Bus Chip-Select Timing 3 [R/W] */ > +#define NILE4_LCST4 0x0120 /* Local Bus Chip-Select Timing 4 [R/W] */ > +#define NILE4_LCST5 0x0128 /* Local Bus Chip-Select Timing 5 [R/W] */ > +#define NILE4_LCST6 0x0130 /* Local Bus Chip-Select Timing 6 [R/W] */ > +#define NILE4_LCST7 0x0138 /* Local Bus Chip-Select Timing 7 [R/W] */ > +#define NILE4_LCST8 0x0140 /* Local Bus Chip-Select Timing 8 [R/W] */ > +#define NILE4_DCSFN 0x0150 /* Device Chip-Select Muxing and Output */ > + /* Enables [R/W] */ > +#define NILE4_DCSIO 0x0158 /* Device Chip-Selects As I/O Bits [R/W] */ > +#define NILE4_BCST 0x0178 /* Local Boot Chip-Select Timing [R/W] */ > + > + > + /* > + * DMA Registers > + */ > + > +#define NILE4_DMACTRL0 0x0180 /* DMA Control 0 [R/W] */ > +#define NILE4_DMASRCA0 0x0188 /* DMA Source Address 0 [R/W] */ > +#define NILE4_DMADESA0 0x0190 /* DMA Destination Address 0 [R/W] */ > +#define NILE4_DMACTRL1 0x0198 /* DMA Control 1 [R/W] */ > +#define NILE4_DMASRCA1 0x01A0 /* DMA Source Address 1 [R/W] */ > +#define NILE4_DMADESA1 0x01A8 /* DMA Destination Address 1 [R/W] */ > + > + > + /* > + * Timer Registers > + */ > + > +#define NILE4_T0CTRL 0x01C0 /* SDRAM Refresh Control [R/W] */ > +#define NILE4_T0CNTR 0x01C8 /* SDRAM Refresh Counter [R/W] */ > +#define NILE4_T1CTRL 0x01D0 /* CPU-Bus Read Time-Out Control [R/W] */ > +#define NILE4_T1CNTR 0x01D8 /* CPU-Bus Read Time-Out Counter [R/W] */ > +#define NILE4_T2CTRL 0x01E0 /* General-Purpose Timer Control [R/W] */ > +#define NILE4_T2CNTR 0x01E8 /* General-Purpose Timer Counter [R/W] */ > +#define NILE4_T3CTRL 0x01F0 /* Watchdog Timer Control [R/W] */ > +#define NILE4_T3CNTR 0x01F8 /* Watchdog Timer Counter [R/W] */ > + > + > + /* > + * PCI Configuration Space Registers > + */ > + > +#define NILE4_PCI_BASE 0x0200 > + > +#define NILE4_VID 0x0200 /* PCI Vendor ID [R] */ > +#define NILE4_DID 0x0202 /* PCI Device ID [R] */ > +#define NILE4_PCICMD 0x0204 /* PCI Command [R/W] */ > +#define NILE4_PCISTS 0x0206 /* PCI Status [R/W] */ > +#define NILE4_REVID 0x0208 /* PCI Revision ID [R] */ > +#define NILE4_CLASS 0x0209 /* PCI Class Code [R] */ > +#define NILE4_CLSIZ 0x020C /* PCI Cache Line Size [R/W] */ > +#define NILE4_MLTIM 0x020D /* PCI Latency Timer [R/W] */ > +#define NILE4_HTYPE 0x020E /* PCI Header Type [R] */ > +#define NILE4_BIST 0x020F /* BIST [R] (unimplemented) */ > +#define NILE4_BARC 0x0210 /* PCI Base Address Register Control [R/W] */ > +#define NILE4_BAR0 0x0218 /* PCI Base Address Register 0 [R/W] */ > +#define NILE4_BAR1 0x0220 /* PCI Base Address Register 1 [R/W] */ > +#define NILE4_CIS 0x0228 /* PCI Cardbus CIS Pointer [R] */ > + /* (unimplemented) */ > +#define NILE4_SSVID 0x022C /* PCI Sub-System Vendor ID [R/W] */ > +#define NILE4_SSID 0x022E /* PCI Sub-System ID [R/W] */ > +#define NILE4_ROM 0x0230 /* Expansion ROM Base Address [R] */ > + /* (unimplemented) */ > +#define NILE4_INTLIN 0x023C /* PCI Interrupt Line [R/W] */ > +#define NILE4_INTPIN 0x023D /* PCI Interrupt Pin [R] */ > +#define NILE4_MINGNT 0x023E /* PCI Min_Gnt [R] (unimplemented) */ > +#define NILE4_MAXLAT 0x023F /* PCI Max_Lat [R] (unimplemented) */ > +#define NILE4_BAR2 0x0240 /* PCI Base Address Register 2 [R/W] */ > +#define NILE4_BAR3 0x0248 /* PCI Base Address Register 3 [R/W] */ > +#define NILE4_BAR4 0x0250 /* PCI Base Address Register 4 [R/W] */ > +#define NILE4_BAR5 0x0258 /* PCI Base Address Register 5 [R/W] */ > +#define NILE4_BAR6 0x0260 /* PCI Base Address Register 6 [R/W] */ > +#define NILE4_BAR7 0x0268 /* PCI Base Address Register 7 [R/W] */ > +#define NILE4_BAR8 0x0270 /* PCI Base Address Register 8 [R/W] */ > +#define NILE4_BARB 0x0278 /* PCI Base Address Register BOOT [R/W] */ > + > + > + /* > + * Serial-Port Registers > + */ > + > +#define NILE4_UART_BASE 0x0300 > + > +#define NILE4_UARTRBR 0x0300 /* UART Receiver Data Buffer [R] */ > +#define NILE4_UARTTHR 0x0300 /* UART Transmitter Data Holding [W] */ > +#define NILE4_UARTIER 0x0308 /* UART Interrupt Enable [R/W] */ > +#define NILE4_UARTDLL 0x0300 /* UART Divisor Latch LSB [R/W] */ > +#define NILE4_UARTDLM 0x0308 /* UART Divisor Latch MSB [R/W] */ > +#define NILE4_UARTIIR 0x0310 /* UART Interrupt ID [R] */ > +#define NILE4_UARTFCR 0x0310 /* UART FIFO Control [W] */ > +#define NILE4_UARTLCR 0x0318 /* UART Line Control [R/W] */ > +#define NILE4_UARTMCR 0x0320 /* UART Modem Control [R/W] */ > +#define NILE4_UARTLSR 0x0328 /* UART Line Status [R/W] */ > +#define NILE4_UARTMSR 0x0330 /* UART Modem Status [R/W] */ > +#define NILE4_UARTSCR 0x0338 /* UART Scratch [R/W] */ > + > +#define NILE4_UART_BASE_BAUD 520833 /* 100 MHz / 12 / 16 */ > + > + > + /* > + * Interrupt Lines > + */ > + > +#define NILE4_INT_CPCE 0 /* CPU-Interface Parity-Error Interrupt */ > +#define NILE4_INT_CNTD 1 /* CPU No-Target Decode Interrupt */ > +#define NILE4_INT_MCE 2 /* Memory-Check Error Interrupt */ > +#define NILE4_INT_DMA 3 /* DMA Controller Interrupt */ > +#define NILE4_INT_UART 4 /* UART Interrupt */ > +#define NILE4_INT_WDOG 5 /* Watchdog Timer Interrupt */ > +#define NILE4_INT_GPT 6 /* General-Purpose Timer Interrupt */ > +#define NILE4_INT_LBRTD 7 /* Local-Bus Ready Timer Interrupt */ > +#define NILE4_INT_INTA 8 /* PCI Interrupt Signal INTA# */ > +#define NILE4_INT_INTB 9 /* PCI Interrupt Signal INTB# */ > +#define NILE4_INT_INTC 10 /* PCI Interrupt Signal INTC# */ > +#define NILE4_INT_INTD 11 /* PCI Interrupt Signal INTD# */ > +#define NILE4_INT_INTE 12 /* PCI Interrupt Signal INTE# (ISA cascade) */ > +#define NILE4_INT_RESV 13 /* Reserved */ > +#define NILE4_INT_PCIS 14 /* PCI SERR# Interrupt */ > +#define NILE4_INT_PCIE 15 /* PCI Internal Error Interrupt */ > + > + > + /* > + * Nile 4 Register Access > + */ > + > +static inline void nile4_sync(void) > +{ > + volatile u32 *p = (volatile u32 *)0xbfc00000; > + (void)(*p); > +} > + > +static inline void nile4_out32(u32 offset, u32 val) > +{ > + *(volatile u32 *)(NILE4_BASE+offset) = val; > + nile4_sync(); > +} > + > +static inline u32 nile4_in32(u32 offset) > +{ > + u32 val = *(volatile u32 *)(NILE4_BASE+offset); > + nile4_sync(); > + return val; > +} > + > +static inline void nile4_out16(u32 offset, u16 val) > +{ > + *(volatile u16 *)(NILE4_BASE+offset) = val; > + nile4_sync(); > +} > + > +static inline u16 nile4_in16(u32 offset) > +{ > + u16 val = *(volatile u16 *)(NILE4_BASE+offset); > + nile4_sync(); > + return val; > +} > + > +static inline void nile4_out8(u32 offset, u8 val) > +{ > + *(volatile u8 *)(NILE4_BASE+offset) = val; > + nile4_sync(); > +} > + > +static inline u8 nile4_in8(u32 offset) > +{ > + u8 val = *(volatile u8 *)(NILE4_BASE+offset); > + nile4_sync(); > + return val; > +} > + > + > + /* > + * Physical Device Address Registers > + */ > + > +extern void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, > + int on_memory_bus, int visible); > + > + > + /* > + * PCI Master Registers > + */ > + > +#define NILE4_PCICMD_IACK 0 /* PCI Interrupt Acknowledge */ > +#define NILE4_PCICMD_IO 1 /* PCI I/O Space */ > +#define NILE4_PCICMD_MEM 3 /* PCI Memory Space */ > +#define NILE4_PCICMD_CFG 5 /* PCI Configuration Space */ > + > + > + /* > + * PCI Address Spaces > + * > + * Note that these are multiplexed using PCIINIT[01]! > + */ > + > +#define NILE4_PCI_IO_BASE 0xa6000000 > +#define NILE4_PCI_MEM_BASE 0xa8000000 > +#define NILE4_PCI_CFG_BASE NILE4_PCI_MEM_BASE > +#define NILE4_PCI_IACK_BASE NILE4_PCI_IO_BASE > + > + > +extern void nile4_set_pmr(u32 pmr, u32 type, u32 addr); > + > + > + /* > + * Interrupt Programming > + */ > + > +#define NUM_I8259_INTERRUPTS 16 > +#define NUM_NILE4_INTERRUPTS 16 > + > +#define IRQ_I8259_CASCADE NILE4_INT_INTE > +#define is_i8259_irq(irq) ((irq) < NUM_I8259_INTERRUPTS) > +#define nile4_to_irq(n) ((n)+NUM_I8259_INTERRUPTS) > +#define irq_to_nile4(n) ((n)-NUM_I8259_INTERRUPTS) > + > +extern void nile4_map_irq(int nile4_irq, int cpu_irq); > +extern void nile4_map_irq_all(int cpu_irq); > +extern void nile4_enable_irq(unsigned int nile4_irq); > +extern void nile4_disable_irq(unsigned int nile4_irq); > +extern void nile4_disable_irq_all(void); > +extern u16 nile4_get_irq_stat(int cpu_irq); > +extern void nile4_enable_irq_output(int cpu_irq); > +extern void nile4_disable_irq_output(int cpu_irq); > +extern void nile4_set_pci_irq_polarity(int pci_irq, int high); > +extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level); > +extern void nile4_clear_irq(int nile4_irq); > +extern void nile4_clear_irq_mask(u32 mask); > +extern u8 nile4_i8259_iack(void); > +extern void nile4_dump_irq_status(void); /* Debug */ > + > +#endif There also was record breaking pile of modpost messages: MODPOST vmlinux.o WARNING: vmlinux.o(.text+0x102b04): Section mismatch: reference to .init.text:pcibios_fixup_bus (between 'pci_scan_child_bus' and 'pci_scan_bus_parented') WARNING: vmlinux.o(.text+0x10775c): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_map_rom' and 'pci_map_rom_copy') WARNING: vmlinux.o(.text+0x107ab4): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_update_resource' and 'pci_claim_resource') WARNING: vmlinux.o(.text+0x108974): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_setup_cardbus' and 'pci_bus_assign_resources') WARNING: vmlinux.o(.text+0x1089d4): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_setup_cardbus' and 'pci_bus_assign_resources') WARNING: vmlinux.o(.text+0x108a34): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_setup_cardbus' and 'pci_bus_assign_resources') WARNING: vmlinux.o(.text+0x108a94): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_setup_cardbus' and 'pci_bus_assign_resources') WARNING: vmlinux.o(.text+0x108c7c): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_bus_assign_resources' and 'pbus_size_mem') WARNING: vmlinux.o(.text+0x108d50): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_bus_assign_resources' and 'pbus_size_mem') WARNING: vmlinux.o(.text+0x108de0): Section mismatch: reference to .init.text:pcibios_resource_to_bus (between 'pci_bus_assign_resources' and 'pbus_size_mem') Which isn't your patch's fault it's just yet more brokeness for the CONFIG_PCI && !CONFIG_HOTPLUG case. So with plenty of fixes your code is now in the -queue tree and you may want to test if it's still in good working order and as usual there is always a little more that could be cleaned and polished ... Ralf