From: Philipp R. <pr...@pa...> - 2000-12-25 12:55:54
|
Most of the Aero 8000 stuff, as well as the RTC changes required for DC. include/asm-sh/{serial,keyboard}.h became slightly uglier, but I don't see a good way to avoid the conditional inclusion and still allow for serial consoles. 2000-12-25 Philipp Rumpf <pr...@tu...> * arch/sh/kernel/rtc.c, include/asm-sh/rtc.h: New files. * arch/sh/config.in [CONFIG_SH_RTC]: made SH onchip RTC support conditional. * arch/sh/kernel/Makefile [CONFIG_SH_RTC]: Likewise. * arch/sh/kernel/mach_foobar.c, arch/sh/kernel/mach_se.c, arch/sh/kernel/mach_hp600.c, arch/sh/kernel/mach_unknown.c: Likewise. * arch/sh/kernel/time.c (get_timer_frequency): modified to work with non-standard RTCs. (do_timer_interrupt): Likewise. (set_rtc_time) (get_rtc_time): removed functions 2000-12-25 Philipp Rumpf <pr...@tu...> * arch/sh/kernel/mach_ec3104.c, arch/sh/kernel/io_ec3104.c, arch/sh/kernel/setup_ec3104.c, include/asm-sh/ec3104.h, include/asm-sh/io_ec3104.h, include/asm-sh/serial-ec3104.h, include/asm-sh/keyboard-ec3104.h, drivers/char/ec3104_keyb.c: New files * arch/sh/config.in, arch/sh/kernel/Makefile, include/asm-sh/io.h, include/asm-sh/irq.h, include/asm-sh/machvec.h: Added support for the EC3104 companion chip. * include/asm-sh/serial.h [CONFIG_SH_EC3104]: Use alternate header file for EC3104. * include/asm-sh/keyboard.h [CONFIG_SH_EC3104]: Likewise. 2000-12-25 Philipp Rumpf <pr...@tu.... * drivers/video/epson1355fb.c: New file * drivers/video/Config.in, drivers/video/Makefile, drivers/video/fbmem.c: added epson 1355 support diff -urNx CVS linuxsh/kernel/arch/sh/config.in linux-aero/arch/sh/config.in --- linuxsh/kernel/arch/sh/config.in Fri Dec 8 13:30:10 2000 +++ linux-aero/arch/sh/config.in Mon Dec 25 03:54:17 2000 @@ -33,8 +33,11 @@ HP690 CONFIG_SH_HP690 \ CqREEK CONFIG_SH_CQREEK \ FOOBAR CONFIG_SH_FOOBAR \ + EC3104 CONFIG_SH_EC3104 \ BareCPU CONFIG_SH_UNKNOWN" Generic +define_bool CONFIG_SH_RTC y + if [ "$CONFIG_SH_HP620" = "y" -o "$CONFIG_SH_HP680" = "y" -o \ "$CONFIG_SH_HP690" = "y" ]; then define_bool CONFIG_SH_HP600 y @@ -73,9 +76,6 @@ mainmenu_option next_comment comment 'General setup' -# Obviously SuperH doesn't *really* have an ISA bus, -# but this variable helps the PCMCIA modules handle -# IRQ requesting properly -- Greg Banks. define_bool CONFIG_ISA y define_bool CONFIG_EISA n define_bool CONFIG_MCA n diff -urNx CVS linuxsh/kernel/arch/sh/kernel/Makefile linux-aero/arch/sh/kernel/Makefile --- linuxsh/kernel/arch/sh/kernel/Makefile Sun Dec 24 03:43:00 2000 +++ linux-aero/arch/sh/kernel/Makefile Mon Dec 25 03:49:39 2000 @@ -21,6 +21,7 @@ obj-$(CONFIG_CF_ENABLER) += cf-enabler.o obj-$(CONFIG_CPU_SH4) += fpu.o obj-$(CONFIG_PCI) += pci-sh.o +obj-$(CONFIG_SH_RTC) += rtc.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o obj-$(CONFIG_SH_HP600) += mach_hp600.o @@ -41,6 +42,7 @@ # Doesn't compile well, so don't include in machine-specific-objs obj-$(CONFIG_HD64465) += setup_hd64465.o io_hd64465.o obj-$(CONFIG_SH_FOOBAR) += mach_foobar.o +obj-$(CONFIG_SH_EC3104) += setup_ec3104.o io_ec3104.o mach_ec3104.o ifeq ($(CONFIG_SH_GENERIC),y) obj-y += $(machine-specific-objs) diff -urNx CVS linuxsh/kernel/arch/sh/kernel/io_ec3104.c linux-aero/arch/sh/kernel/io_ec3104.c --- linuxsh/kernel/arch/sh/kernel/io_ec3104.c Wed Dec 31 16:00:00 1969 +++ linux-aero/arch/sh/kernel/io_ec3104.c Mon Dec 25 02:59:52 2000 @@ -0,0 +1,83 @@ +/* + * linux/arch/sh/kernel/io_ec3104.c + * EC3104 companion chip support + * + * Copyright (C) 2000 Philipp Rumpf <pr...@tu...> + * + */ +/* EC3104 note: + * This code was written without any documentation about the EC3104 chip. While + * I hope I got most of the basic functionality right, the register names I use + * are most likely completely different from those in the chip documentation. + * + * If you have any further information about the EC3104, please tell me + * (pr...@tu...). + */ + + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/io.h> +#include <asm/page.h> +#include <asm/ec3104.h> + +/* + * EC3104 has a real ISA bus which we redirect low port accesses to (the + * actual device on mine is a ESS 1868, and I don't want to hack the driver + * more than strictly necessary). I am not going to duplicate the + * hard coding of PC addresses (for the 16550s aso) here though; it's just + * too ugly. + */ + +#define low_port(port) ((port) < 0x10000) + +static inline unsigned long port2addr(unsigned long port) +{ + switch(port >> 16) { + case 0: + return EC3104_ISA_BASE + port * 2; + + /* XXX hack. it's unclear what to do about the serial ports */ + case 1: + return EC3104_BASE + (port&0xffff) * 4; + + default: + /* XXX PCMCIA */ + return 0; + } +} + +unsigned char ec3104_inb(unsigned long port) +{ + u8 ret; + + ret = *(volatile u8 *)port2addr(port); + + return ret; +} + +unsigned short ec3104_inw(unsigned long port) +{ + BUG(); +} + +unsigned long ec3104_inl(unsigned long port) +{ + BUG(); +} + +void ec3104_outb(unsigned char data, unsigned long port) +{ + *(volatile u8 *)port2addr(port) = data; +} + +void ec3104_outw(unsigned short data, unsigned long port) +{ + BUG(); +} + +void ec3104_outl(unsigned long data, unsigned long port) +{ + BUG(); +} diff -urNx CVS linuxsh/kernel/arch/sh/kernel/mach_ec3104.c linux-aero/arch/sh/kernel/mach_ec3104.c --- linuxsh/kernel/arch/sh/kernel/mach_ec3104.c Wed Dec 31 16:00:00 1969 +++ linux-aero/arch/sh/kernel/mach_ec3104.c Mon Dec 25 02:59:52 2000 @@ -0,0 +1,69 @@ +/* + * linux/arch/sh/kernel/mach_ec3104.c + * EC3104 companion chip support + * + * Copyright (C) 2000 Philipp Rumpf <pr...@tu...> + * + */ +/* EC3104 note: + * This code was written without any documentation about the EC3104 chip. While + * I hope I got most of the basic functionality right, the register names I use + * are most likely completely different from those in the chip documentation. + * + * If you have any further information about the EC3104, please tell me + * (pr...@tu...). + */ + +#include <linux/init.h> + +#include <asm/machvec.h> +#include <asm/rtc.h> +#include <asm/machvec_init.h> + +#include <asm/io.h> +#include <asm/irq.h> + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_ec3104 __initmv = { + mv_name: "EC3104", + + mv_nr_irqs: 96, + + mv_inb: ec3104_inb, + mv_inw: ec3104_inw, + mv_inl: ec3104_inl, + mv_outb: ec3104_outb, + mv_outw: ec3104_outw, + mv_outl: ec3104_outl, + + mv_inb_p: generic_inb_p, + mv_inw_p: generic_inw, + mv_inl_p: generic_inl, + mv_outb_p: generic_outb_p, + mv_outw_p: generic_outw, + mv_outl_p: generic_outl, + + mv_insb: generic_insb, + mv_insw: generic_insw, + mv_insl: generic_insl, + mv_outsb: generic_outsb, + mv_outsw: generic_outsw, + mv_outsl: generic_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_irq_demux: ec3104_irq_demux, + + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, +}; + +ALIAS_MV(ec3104) diff -urNx CVS linuxsh/kernel/arch/sh/kernel/mach_foobar.c linux-aero/arch/sh/kernel/mach_foobar.c --- linuxsh/kernel/arch/sh/kernel/mach_foobar.c Mon Dec 11 06:30:04 2000 +++ linux-aero/arch/sh/kernel/mach_foobar.c Mon Dec 25 02:59:52 2000 @@ -16,6 +16,7 @@ #include <linux/init.h> #include <asm/machvec.h> +#include <asm/rtc.h> #include <asm/machvec_init.h> #include <asm/io.h> @@ -60,6 +61,9 @@ mv_writel: generic_writel, mv_irq_demux: hd64465_irq_demux, + + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_hd64465: 1, }; diff -urNx CVS linuxsh/kernel/arch/sh/kernel/mach_hp600.c linux-aero/arch/sh/kernel/mach_hp600.c --- linuxsh/kernel/arch/sh/kernel/mach_hp600.c Mon Dec 11 06:30:04 2000 +++ linux-aero/arch/sh/kernel/mach_hp600.c Mon Dec 25 02:59:52 2000 @@ -12,6 +12,7 @@ #include <linux/init.h> #include <asm/machvec.h> +#include <asm/rtc.h> #include <asm/machvec_init.h> #include <asm/io_hd64461.h> @@ -57,6 +58,9 @@ mv_irq_demux: hd64461_irq_demux, + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, + mv_hw_hp600: 1, mv_hw_hp620: 1, mv_hw_hd64461: 1, @@ -99,6 +103,9 @@ mv_irq_demux: hd64461_irq_demux, + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, + mv_hw_hp600: 1, mv_hw_hp680: 1, mv_hw_hd64461: 1, @@ -140,6 +147,9 @@ mv_writel: generic_writel, mv_irq_demux: hd64461_irq_demux, + + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_hp600: 1, mv_hw_hp690: 1, diff -urNx CVS linuxsh/kernel/arch/sh/kernel/mach_se.c linux-aero/arch/sh/kernel/mach_se.c --- linuxsh/kernel/arch/sh/kernel/mach_se.c Mon Dec 11 06:30:04 2000 +++ linux-aero/arch/sh/kernel/mach_se.c Mon Dec 25 02:59:52 2000 @@ -13,6 +13,7 @@ #include <linux/init.h> #include <asm/machvec.h> +#include <asm/rtc.h> #include <asm/machvec_init.h> #include <asm/io_se.h> @@ -74,6 +75,9 @@ #ifdef CONFIG_HEARTBEAT mv_heartbeat: heartbeat_se, #endif + + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_se: 1, }; diff -urNx CVS linuxsh/kernel/arch/sh/kernel/mach_unknown.c linux-aero/arch/sh/kernel/mach_unknown.c --- linuxsh/kernel/arch/sh/kernel/mach_unknown.c Mon Dec 11 06:30:04 2000 +++ linux-aero/arch/sh/kernel/mach_unknown.c Mon Dec 25 02:59:52 2000 @@ -64,5 +64,8 @@ mv_iounmap: unknown_iounmap, mv_isa_port2addr: unknown_isa_port2addr, + + mv_rtc_gettimeofday: sh_rtc_gettimeofday, + mv_rtc_settimeofday: sh_rtc_settimeofday, }; ALIAS_MV(unknown) diff -urNx CVS linuxsh/kernel/arch/sh/kernel/rtc.c linux-aero/arch/sh/kernel/rtc.c --- linuxsh/kernel/arch/sh/kernel/rtc.c Wed Dec 31 16:00:00 1969 +++ linux-aero/arch/sh/kernel/rtc.c Mon Dec 25 02:59:52 2000 @@ -0,0 +1,178 @@ +/* + * linux/arch/sh/kernel/rtc.c -- SH3 / SH4 on-chip RTC support + * + * Copyright (C) 2000 Philipp Rumpf <pr...@tu...> + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/time.h> + +#include <asm/io.h> +#include <asm/rtc.h> + +/* RCR1 Bits */ +#define RCR1_CF 0x80 /* Carry Flag */ +#define RCR1_CIE 0x10 /* Carry Interrupt Enable */ +#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */ +#define RCR1_AF 0x01 /* Alarm Flag */ + +/* RCR2 Bits */ +#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */ +#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */ +#define RCR2_RTCEN 0x08 /* ENable RTC */ +#define RCR2_ADJ 0x04 /* ADJustment (30-second) */ +#define RCR2_RESET 0x02 /* Reset bit */ +#define RCR2_START 0x01 /* Start bit */ + + +#if defined(__sh3__) +/* SH-3 RTC */ +#define R64CNT 0xfffffec0 +#define RSECCNT 0xfffffec2 +#define RMINCNT 0xfffffec4 +#define RHRCNT 0xfffffec6 +#define RWKCNT 0xfffffec8 +#define RDAYCNT 0xfffffeca +#define RMONCNT 0xfffffecc +#define RYRCNT 0xfffffece +#define RSECAR 0xfffffed0 +#define RMINAR 0xfffffed2 +#define RHRAR 0xfffffed4 +#define RWKAR 0xfffffed6 +#define RDAYAR 0xfffffed8 +#define RMONAR 0xfffffeda +#define RCR1 0xfffffedc +#define RCR2 0xfffffede +#elif defined(__SH4__) +/* SH-4 RTC */ +#define R64CNT 0xffc80000 +#define RSECCNT 0xffc80004 +#define RMINCNT 0xffc80008 +#define RHRCNT 0xffc8000c +#define RWKCNT 0xffc80010 +#define RDAYCNT 0xffc80014 +#define RMONCNT 0xffc80018 +#define RYRCNT 0xffc8001c /* 16bit */ +#define RSECAR 0xffc80020 +#define RMINAR 0xffc80024 +#define RHRAR 0xffc80028 +#define RWKAR 0xffc8002c +#define RDAYAR 0xffc80030 +#define RMONAR 0xffc80034 +#define RCR1 0xffc80038 +#define RCR2 0xffc8003c +#endif + +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +void sh_rtc_gettimeofday(struct timeval *tv) +{ + unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100; + + again: + do { + ctrl_outb(0, RCR1); /* Clear CF-bit */ + sec128 = ctrl_inb(RSECCNT); + sec = ctrl_inb(RSECCNT); + min = ctrl_inb(RMINCNT); + hr = ctrl_inb(RHRCNT); + wk = ctrl_inb(RWKCNT); + day = ctrl_inb(RDAYCNT); + mon = ctrl_inb(RMONCNT); +#if defined(__SH4__) + yr = ctrl_inw(RYRCNT); + yr100 = (yr >> 8); + yr &= 0xff; +#else + yr = ctrl_inb(RYRCNT); + yr100 = (yr == 0x99) ? 0x19 : 0x20; +#endif + } while ((ctrl_inb(RCR1) & RCR1_CF) != 0); + + BCD_TO_BIN(yr100); + BCD_TO_BIN(yr); + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hr); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + + if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || + hr > 23 || min > 59 || sec > 59) { + printk(KERN_ERR + "SH RTC: invalid value, resetting to 1 Jan 2000\n"); + ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ + ctrl_outb(0, RSECCNT); + ctrl_outb(0, RMINCNT); + ctrl_outb(0, RHRCNT); + ctrl_outb(6, RWKCNT); + ctrl_outb(1, RDAYCNT); + ctrl_outb(1, RMONCNT); +#if defined(__SH4__) + ctrl_outw(0x2000, RYRCNT); +#else + ctrl_outb(0, RYRCNT); +#endif + ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */ + goto again; + } + + tv->tv_sec = mktime(yr100 * 100 + yr, mon, day, hr, min, sec); + tv->tv_usec = (sec128 * 1000000) / 128; +} + +static int set_rtc_time(unsigned long nowtime) +{ + extern int abs (int); + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + + ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */ + + cmos_minutes = ctrl_inb(RMINCNT); + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + ctrl_outb(real_seconds, RSECCNT); + ctrl_outb(real_minutes, RMINCNT); + } else { + printk(KERN_WARNING + "set_rtc_time: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */ + + return retval; +} + +int sh_rtc_settimeofday(const struct timeval *tv) +{ + return set_rtc_time(tv->tv_sec); +} + + diff -urNx CVS linuxsh/kernel/arch/sh/kernel/setup_ec3104.c linux-aero/arch/sh/kernel/setup_ec3104.c --- linuxsh/kernel/arch/sh/kernel/setup_ec3104.c Wed Dec 31 16:00:00 1969 +++ linux-aero/arch/sh/kernel/setup_ec3104.c Mon Dec 25 02:59:52 2000 @@ -0,0 +1,221 @@ +/* + * linux/arch/sh/kernel/setup_ec3104.c + * EC3104 companion chip support + * + * Copyright (C) 2000 Philipp Rumpf <pr...@tu...> + * + */ +/* EC3104 note: + * This code was written without any documentation about the EC3104 chip. While + * I hope I got most of the basic functionality right, the register names I use + * are most likely completely different from those in the chip documentation. + * + * If you have any further information about the EC3104, please tell me + * (pr...@tu...). + */ + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/types.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/ec3104.h> + +/* This is for debugging mostly; here's the table that I intend to keep + * in here: + * + * index function base addr power interrupt bit + * 0 power b0ec0000 --- 00000001 (unused) + * 1 irqs b0ec1000 --- 00000002 (unused) + * 2 ?? b0ec2000 b0ec0008 00000004 + * 3 PS2 (1) b0ec3000 b0ec000c 00000008 + * 4 PS2 (2) b0ec4000 b0ec0010 00000010 + * 5 ?? b0ec5000 b0ec0014 00000020 + * 6 I2C b0ec6000 b0ec0018 00000040 + * 7 serial (1) b0ec7000 b0ec001c 00000080 + * 8 serial (2) b0ec8000 b0ec0020 00000100 + * 9 serial (3) b0ec9000 b0ec0024 00000200 + * 10 serial (4) b0eca000 b0ec0028 00000400 + * 16 pcmcia (1) b0ed0000 b0ec0040 00010000 + * 17 pcmcia (2) b0ed1000 b0ec0044 00020000 + */ + +static char *ec3104_name(unsigned index) +{ + switch(index) { + case 0: + return "power management"; + case 1: + return "interrupts"; + case 3: + return "PS2 (1)"; + case 4: + return "PS2 (2)"; + case 5: + return "I2C (1)"; + case 6: + return "I2C (2)"; + case 7: + return "serial (1)"; + case 8: + return "serial (2)"; + case 9: + return "serial (3)"; + case 10: + return "serial (4)"; + case 16: + return "pcmcia (1)"; + case 17: + return "pcmcia (2)"; + default: { + static char buf[32]; + + sprintf(buf, "unknown (%d)", index); + + return buf; + } + } +} + +/* I used the register names from another interrupt controller I worked with, + * since it seems to be identical to the ec3104 except that all bits are + * inverted: + * + * IRR: Interrupt Request Register (pending and enabled interrupts) + * IMR: Interrupt Mask Register (which interrupts are enabled) + * IPR: Interrupt Pending Register (pending interrupts, even disabled ones) + * + * 0 bits mean pending or enabled, 1 bits mean not pending or disabled. all + * IRQs seem to be level-triggered. + */ + +#define EC3104_IRR (EC3104_BASE + 0x1000) +#define EC3104_IMR (EC3104_BASE + 0x1004) +#define EC3104_IPR (EC3104_BASE + 0x1008) + +#define ctrl_readl(addr) (*(volatile u32 *)(addr)) +#define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data)) +#define ctrl_readb(addr) (*(volatile u8 *)(addr)) + +static inline u32 ec3104_irq2mask(unsigned int irq) +{ + return (1 << (irq - EC3104_IRQBASE)); +} + +static inline void mask_ec3104_irq(unsigned int irq) +{ + u32 mask; + + mask = ctrl_readl(EC3104_IMR); + + mask |= ec3104_irq2mask(irq); + + ctrl_writel(mask, EC3104_IMR); +} + +static inline void unmask_ec3104_irq(unsigned int irq) +{ + u32 mask; + + mask = ctrl_readl(EC3104_IMR); + + mask &= ~ec3104_irq2mask(irq); + + ctrl_writel(mask, EC3104_IMR); +} + +static void disable_ec3104_irq(unsigned int irq) +{ + mask_ec3104_irq(irq); +} + +static void enable_ec3104_irq(unsigned int irq) +{ + unmask_ec3104_irq(irq); +} + +static void mask_and_ack_ec3104_irq(unsigned int irq) +{ + mask_ec3104_irq(irq); +} + +static void end_ec3104_irq(unsigned int irq) +{ + unmask_ec3104_irq(irq); +} + +static unsigned int startup_ec3104_irq(unsigned int irq) +{ + unmask_ec3104_irq(irq); + + return 0; +} + +static void shutdown_ec3104_irq(unsigned int irq) +{ + mask_ec3104_irq(irq); + +} + +static struct hw_interrupt_type ec3104_int = { + typename: "EC3104", + enable: enable_ec3104_irq, + disable: disable_ec3104_irq, + ack: mask_and_ack_ec3104_irq, + end: end_ec3104_irq, + startup: startup_ec3104_irq, + shutdown: shutdown_ec3104_irq, +}; + +/* Yuck. the _demux API is ugly */ +int ec3104_irq_demux(int irq) +{ + if (irq == EC3104_IRQ) { + unsigned int mask; + + mask = ctrl_readl(EC3104_IRR); + + if (mask == 0xffffffff) + return EC3104_IRQ; + else + return EC3104_IRQBASE + ffz(mask); + } + + return irq; +} + +int __init setup_ec3104(void) +{ + char str[8]; + int i; + + if (!MACH_EC3104) + printk("!MACH_EC3104\n"); + + if (0) + return 0; + + for (i=0; i<8; i++) + str[i] = ctrl_readb(EC3104_BASE + i); + + for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) + irq_desc[i].handler = &ec3104_int; + + printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", + str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); + + + /* mask all interrupts. this should have been done by the boot + * loader for us but we want to be sure ... */ + ctrl_writel(0xffffffff, EC3104_IMR); + + return 0; +} + +module_init(setup_ec3104); diff -urNx CVS linuxsh/kernel/arch/sh/kernel/time.c linux-aero/arch/sh/kernel/time.c --- linuxsh/kernel/arch/sh/kernel/time.c Mon Dec 11 06:12:13 2000 +++ linux-aero/arch/sh/kernel/time.c Mon Dec 25 02:59:52 2000 @@ -28,6 +28,7 @@ #include <asm/irq.h> #include <asm/delay.h> #include <asm/machvec.h> +#include <asm/rtc.h> #include <linux/timex.h> #include <linux/irq.h> @@ -38,20 +39,6 @@ #define TMU0_TCR_CALIB 0x0000 -/* RCR1 Bits */ -#define RCR1_CF 0x80 /* Carry Flag */ -#define RCR1_CIE 0x10 /* Carry Interrupt Enable */ -#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */ -#define RCR1_AF 0x01 /* Alarm Flag */ - -/* RCR2 Bits */ -#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */ -#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */ -#define RCR2_RTCEN 0x08 /* ENable RTC */ -#define RCR2_ADJ 0x04 /* ADJustment (30-second) */ -#define RCR2_RESET 0x02 /* Reset bit */ -#define RCR2_START 0x01 /* Start bit */ - #if defined(__sh3__) #define TMU_TOCR 0xfffffe90 /* Byte access */ #define TMU_TSTR 0xfffffe92 /* Byte access */ @@ -61,25 +48,6 @@ #define TMU0_TCR 0xfffffe9c /* Word access */ #define FRQCR 0xffffff80 - -/* SH-3 RTC */ -#define R64CNT 0xfffffec0 -#define RSECCNT 0xfffffec2 -#define RMINCNT 0xfffffec4 -#define RHRCNT 0xfffffec6 -#define RWKCNT 0xfffffec8 -#define RDAYCNT 0xfffffeca -#define RMONCNT 0xfffffecc -#define RYRCNT 0xfffffece -#define RSECAR 0xfffffed0 -#define RMINAR 0xfffffed2 -#define RHRAR 0xfffffed4 -#define RWKAR 0xfffffed6 -#define RDAYAR 0xfffffed8 -#define RMONAR 0xfffffeda -#define RCR1 0xfffffedc -#define RCR2 0xfffffede - #elif defined(__SH4__) #define TMU_TOCR 0xffd80000 /* Byte access */ #define TMU_TSTR 0xffd80004 /* Byte access */ @@ -89,32 +57,6 @@ #define TMU0_TCR 0xffd80010 /* Word access */ #define FRQCR 0xffc00000 - -/* SH-4 RTC */ -#define R64CNT 0xffc80000 -#define RSECCNT 0xffc80004 -#define RMINCNT 0xffc80008 -#define RHRCNT 0xffc8000c -#define RWKCNT 0xffc80010 -#define RDAYCNT 0xffc80014 -#define RMONCNT 0xffc80018 -#define RYRCNT 0xffc8001c /* 16bit */ -#define RSECAR 0xffc80020 -#define RMINAR 0xffc80024 -#define RHRAR 0xffc80028 -#define RWKAR 0xffc8002c -#define RDAYAR 0xffc80030 -#define RMONAR 0xffc80034 -#define RCR1 0xffc80038 -#define RCR2 0xffc8003c -#endif - -#ifndef BCD_TO_BIN -#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) -#endif - -#ifndef BIN_TO_BCD -#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) #endif extern rwlock_t xtime_lock; @@ -220,46 +162,6 @@ write_unlock_irq(&xtime_lock); } -static int set_rtc_time(unsigned long nowtime) -{ - extern int abs (int); - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - - ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */ - - cmos_minutes = ctrl_inb(RMINCNT); - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - ctrl_outb(real_seconds, RSECCNT); - ctrl_outb(real_minutes, RMINCNT); - } else { - printk(KERN_WARNING - "set_rtc_time: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */ - - return retval; -} - /* last time the RTC clock got updated */ static long last_rtc_update; @@ -289,7 +191,7 @@ xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (set_rtc_time(xtime.tv_sec) == 0) + if (sh_mv.mv_rtc_settimeofday(&xtime) == 0) last_rtc_update = xtime.tv_sec; else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ @@ -322,64 +224,12 @@ write_unlock(&xtime_lock); } -static unsigned long get_rtc_time(void) -{ - unsigned int sec, min, hr, wk, day, mon, yr, yr100; - - again: - do { - ctrl_outb(0, RCR1); /* Clear CF-bit */ - sec = ctrl_inb(RSECCNT); - min = ctrl_inb(RMINCNT); - hr = ctrl_inb(RHRCNT); - wk = ctrl_inb(RWKCNT); - day = ctrl_inb(RDAYCNT); - mon = ctrl_inb(RMONCNT); -#if defined(__SH4__) - yr = ctrl_inw(RYRCNT); - yr100 = (yr >> 8); - yr &= 0xff; -#else - yr = ctrl_inb(RYRCNT); - yr100 = (yr == 0x99) ? 0x19 : 0x20; -#endif - } while ((ctrl_inb(RCR1) & RCR1_CF) != 0); - - BCD_TO_BIN(yr100); - BCD_TO_BIN(yr); - BCD_TO_BIN(mon); - BCD_TO_BIN(day); - BCD_TO_BIN(hr); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - - if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || - hr > 23 || min > 59 || sec > 59) { - printk(KERN_ERR - "SH RTC: invalid value, resetting to 1 Jan 2000\n"); - ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ - ctrl_outb(0, RSECCNT); - ctrl_outb(0, RMINCNT); - ctrl_outb(0, RHRCNT); - ctrl_outb(6, RWKCNT); - ctrl_outb(1, RDAYCNT); - ctrl_outb(1, RMONCNT); -#if defined(__SH4__) - ctrl_outw(0x2000, RYRCNT); -#else - ctrl_outb(0, RYRCNT); -#endif - ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */ - goto again; - } - - return mktime(yr100 * 100 + yr, mon, day, hr, min, sec); -} - static unsigned int __init get_timer_frequency(void) { u32 freq; - u8 r64cnt; + struct timeval tv1, tv2; + unsigned long diff_usec; + unsigned long factor; /* Setup the timer: We don't want to generate interrupts, just * have it count down at its natural rate. @@ -390,22 +240,37 @@ ctrl_outl(0xffffffff, TMU0_TCOR); ctrl_outl(0xffffffff, TMU0_TCNT); - /* wait until the current 1/128th second is over */ - r64cnt = ctrl_inb(R64CNT); - while (ctrl_inb(R64CNT) == r64cnt); - + rtc_gettimeofday(&tv2); + + do { + rtc_gettimeofday(&tv1); + } while (tv1.tv_usec == tv2.tv_usec && tv1.tv_sec == tv2.tv_sec); + /* actually start the timer */ ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); - /* wait 1/128th of a second */ - r64cnt = ctrl_inb(R64CNT); - while (ctrl_inb(R64CNT) == r64cnt); - + do { + rtc_gettimeofday(&tv2); + } while (tv1.tv_usec == tv2.tv_usec && tv1.tv_sec == tv2.tv_sec); + freq = 0xffffffff - ctrl_inl(TMU0_TCNT); - - freq *= 128; + if (tv2.tv_usec < tv1.tv_usec) { + tv2.tv_usec += 1000000; + tv2.tv_sec--; + } + + diff_usec = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + + /* this should work well if the RTC has a precision of n Hz, where + * n is an integer. I don't think we have to worry about the other + * cases. */ + factor = (1000000 + diff_usec/2) / diff_usec; + + if (factor * diff_usec > 1100000 || + factor * diff_usec < 900000) + panic("weird RTC (diff_usec %ld)", diff_usec); - return freq; + return freq * factor; } static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; @@ -426,8 +291,7 @@ static int pfc_table[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; #endif - xtime.tv_sec = get_rtc_time(); - xtime.tv_usec = 0; + rtc_gettimeofday(&xtime); setup_irq(TIMER_IRQ, &irq0); diff -urNx CVS linuxsh/kernel/drivers/char/Makefile linux-aero/drivers/char/Makefile --- linuxsh/kernel/drivers/char/Makefile Sun Dec 24 03:43:24 2000 +++ linux-aero/drivers/char/Makefile Mon Dec 25 02:59:52 2000 @@ -68,6 +68,11 @@ KEYBD = scan_keyb.o hp600_keyb.o CONSOLE = console.o endif + ifeq ($(CONFIG_SH_EC3104),y) + KEYMAP = defkeymap.o + KEYBD = ec3104_keyb.o + CONSOLE = console.o + endif endif ifeq ($(CONFIG_DECSTATION),y) diff -urNx CVS linuxsh/kernel/drivers/char/ec3104_keyb.c linux-aero/drivers/char/ec3104_keyb.c --- linuxsh/kernel/drivers/char/ec3104_keyb.c Wed Dec 31 16:00:00 1969 +++ linux-aero/drivers/char/ec3104_keyb.c Mon Dec 25 03:51:12 2000 @@ -0,0 +1,333 @@ +/* + * linux/drivers/char/ec3104_keyb.c + * + * Copyright (C) 2000 Philipp Rumpf <pr...@tu...> + * + * based on linux/drivers/char/pc_keyb.c, which had the following comments: + * + * Separation of the PC low-level part by Geert Uytterhoeven, May 1997 + * See keyboard.c for the whole history. + * + * Major cleanup by Martin Mares, May 1997 + * + * Combined the keyboard and PS/2 mouse handling into one file, + * because they share the same hardware. + * Johan Myreen <je...@ik...> 1998-10-08. + * + * Code fixes to handle mouse ACKs properly. + * C. Scott Ananian <can...@al...> 1999-01-29. + */ +/* EC3104 note: + * This code was written without any documentation about the EC3104 chip. While + * I hope I got most of the basic functionality right, the register names I use + * are most likely completely different from those in the chip documentation. + * + * If you have any further information about the EC3104, please tell me + * (pr...@tu...). + */ + +#include <linux/config.h> + +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/tty.h> +#include <linux/mm.h> +#include <linux/signal.h> +#include <linux/init.h> +#include <linux/kbd_ll.h> +#include <linux/delay.h> +#include <linux/random.h> +#include <linux/poll.h> +#include <linux/miscdevice.h> +#include <linux/malloc.h> +#include <linux/kbd_kern.h> +#include <linux/smp_lock.h> + +#include <asm/keyboard.h> +#include <asm/bitops.h> +#include <asm/uaccess.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/ec3104.h> + +#include <asm/io.h> + +/* Some configuration switches are present in the include file... */ + +#include <linux/pc_keyb.h> + +#define MSR_CTS 0x10 +#define MCR_RTS 0x02 +#define LSR_DR 0x01 + +static struct ec3104_keyb_struct { + u8 packet[3]; + int pos; + + u8 cached_mcr; + u8 last_msr; +} ec3104_keyb; + +/* Simple translation table for the SysRq keys */ + + +#ifdef CONFIG_MAGIC_SYSRQ +unsigned char ec3104_kbd_sysrq_xlate[128] = + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/"; /* 0x60 - 0x6f */ +#endif + +static void kbd_write_command_w(int data); +static void kbd_write_output_w(int data); +#ifdef CONFIG_PSMOUSE +static void aux_write_ack(int val); +static void __aux_write_ack(int val); +#endif + +static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; +static unsigned char handle_kbd_event(void); + +/* used only by send_data - set by keyboard_interrupt */ +static volatile unsigned char reply_expected; +static volatile unsigned char acknowledge; +static volatile unsigned char resend; + + +int ec3104_kbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + return 0; +} + +int ec3104_kbd_getkeycode(unsigned int scancode) +{ + return 0; +} + + +/* yes, it probably would be faster to use an array. I don't care. */ + +static inline unsigned char ec3104_scan2key(unsigned char scancode) +{ + switch (scancode) { + case 1: /* '`' */ + return 41; + + case 2 ... 27: + return scancode; + + case 28: /* '\\' */ + return 43; + + case 29 ... 39: + return scancode + 1; + + case 40: /* '\r' */ + return 28; + + case 41 ... 50: + return scancode + 3; + + case 51: /* ' ' */ + return 57; + + case 52: /* escape */ + return 1; + + case 54: /* insert/delete (labelled delete) */ + /* this should arguably be 110, but I'd like to have ctrl-alt-del + * working with a standard keymap */ + return 111; + + case 55: /* left */ + return 105; + case 56: /* home */ + return 102; + case 57: /* end */ + return 107; + case 58: /* up */ + return 103; + case 59: /* down */ + return 108; + case 60: /* pgup */ + return 104; + case 61: /* pgdown */ + return 109; + case 62: /* right */ + return 106; + + case 79 ... 88: /* f1 - f10 */ + return scancode - 20; + + case 89 ... 90: /* f11 - f12 */ + return scancode - 2; + + case 91: /* left shift */ + return 42; + + case 92: /* right shift */ + return 54; + + case 93: /* left alt */ + return 56; + case 94: /* right alt */ + return 100; + case 95: /* left ctrl */ + return 29; + case 96: /* right ctrl */ + return 97; + + case 97: /* caps lock */ + return 58; + case 102: /* left windows */ + return 125; + case 103: /* right windows */ + return 126; + + case 106: /* Fn */ + /* this is wrong. */ + return 84; + } +} + +int ec3104_kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + scancode &= 0x7f; + + *keycode = ec3104_scan2key(scancode); + + return 1; +} + +char ec3104_kbd_unexpected_up(unsigned char keycode) +{ + return 0200; +} + +static inline void handle_keyboard_event(unsigned char scancode) +{ +#ifdef CONFIG_VT + handle_scancode(scancode, !(scancode & 0x80)); +#endif + tasklet_schedule(&keyboard_tasklet); +} + +void ec3104_kbd_leds(unsigned char leds) +{ +} + +static void ec3104_keyb_receive(struct ec3104_keyb_struct *k) +{ + k->packet[k->pos++] = ctrl_inb(EC3104_SER4_DATA); + + /* All E5 packets I've seen look like this: + * 0x88 <scancode> <mystery byte>. mystery byte seems to depend on the + * key that was pressed only so we ignore it (scancode has all the + * information we need). + */ + + if (k->pos == 3) { + if (k->packet[0] != 0x88) + printk(KERN_WARNING "got bogus EC3104/E5 packet (%02x)\n", + k->packet[0]); + + handle_keyboard_event(k->packet[1]); + + k->pos = 0; + } +} + +static void ec3104_keyb_interrupt(int irq, void *data, struct pt_regs *regs) +{ + struct ec3104_keyb_struct *k = &ec3104_keyb; + u8 msr, lsr; + + kbd_pt_regs = regs; + + msr = ctrl_inb(EC3104_SER4_MSR); + + if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) { + if (k->cached_mcr & MCR_RTS) + printk("confused: RTS already high\n"); + /* CTS went high. Send RTS. */ + k->cached_mcr |= MCR_RTS; + + ctrl_outb(k->cached_mcr, EC3104_SER4_MCR); + } else if ((!(msr & MSR_CTS)) && (k->last_msr & MSR_CTS)) { + /* CTS went low. */ + if (!(k->cached_mcr & MCR_RTS)) + printk("confused: RTS already low\n"); + + k->cached_mcr &= ~MCR_RTS; + + ctrl_outb(k->cached_mcr, EC3104_SER4_MCR); + } + + k->last_msr = msr; + + lsr = ctrl_inb(EC3104_SER4_LSR); + + if (lsr & LSR_DR) + ec3104_keyb_receive(k); +} + +static void ec3104_keyb_clear_state(void) +{ + struct ec3104_keyb_struct *k = &ec3104_keyb; + u8 msr, lsr; + + /* we want CTS to be low */ + k->last_msr = 0; + + for (;;) { + schedule_timeout(HZ/10); + + msr = ctrl_inb(EC3104_SER4_MSR); + + lsr = ctrl_inb(EC3104_SER4_LSR); + + if (lsr & LSR_DR) { + ec3104_keyb_receive(k); + continue; + } + + if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) { + if (k->cached_mcr & MCR_RTS) + printk("confused: RTS already high\n"); + /* CTS went high. Send RTS. */ + k->cached_mcr |= MCR_RTS; + + ctrl_outb(k->cached_mcr, EC3104_SER4_MCR); + } else if ((!(msr & MSR_CTS)) && (k->last_msr & MSR_CTS)) { + /* CTS went low. */ + if (!(k->cached_mcr & MCR_RTS)) + printk("confused: RTS already low\n"); + + k->cached_mcr &= ~MCR_RTS; + + ctrl_outb(k->cached_mcr, EC3104_SER4_MCR); + } else + break; + + k->last_msr = msr; + + continue; + } +} + +void __init ec3104_kbd_init_hw(void) +{ + ec3104_keyb.last_msr = ctrl_inb(EC3104_SER4_MSR); + ec3104_keyb.cached_mcr = ctrl_inb(EC3104_SER4_MCR); + + ec3104_keyb_clear_state(); + + /* Ok, finally allocate the IRQ, and off we go.. */ + request_irq(EC3104_IRQ_SER4, ec3104_keyb_interrupt, 0, "keyboard", NULL); +} diff -urNx CVS linuxsh/kernel/drivers/video/Config.in linux-aero/drivers/video/Config.in --- linuxsh/kernel/drivers/video/Config.in Sun Dec 24 03:44:44 2000 +++ linux-aero/drivers/video/Config.in Mon Dec 25 02:59:52 2000 @@ -98,6 +98,7 @@ bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX fi fi + bool 'Epson 1355 framebuffer support' CONFIG_FB_E1355 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_PCI" != "n" ]; then tristate ' Matrox acceleration (EXPERIMENTAL)' CONFIG_FB_MATROX diff -urNx CVS linuxsh/kernel/drivers/video/Makefile linux-aero/drivers/video/Makefile --- linuxsh/kernel/drivers/video/Makefile Sun Dec 24 03:44:44 2000 +++ linux-aero/drivers/video/Makefile Mon Dec 25 02:59:52 2000 @@ -100,6 +100,7 @@ obj-$(CONFIG_FB_SA1100) += sa1100fb.o obj-$(CONFIG_FB_VIRTUAL) += vfb.o obj-$(CONFIG_FB_HIT) += hitfb.o fbgen.o +obj-$(CONFIG_FB_E1355) += epson1355fb.o fbgen.o # Generic Low Level Drivers diff -urNx CVS linuxsh/kernel/drivers/video/epson1355fb.c linux-aero/drivers/video/epson1355fb.c --- linuxsh/kernel/drivers/video/epson1355fb.c Wed Dec 31 16:00:00 1969 +++ linux-aero/drivers/video/epson1355fb.c Mon Dec 25 02:59:52 2000 @@ -0,0 +1,554 @@ +/* + * linux/drivers/video/epson1355fb.c + * -- Support for the Epson SED1355 LCD/CRT controller + * + * Copyright (C) 2000 Philipp Rumpf <pr...@tu...> + * + * based on linux/drivers/video/skeletonfb.c, which was + * Created 28 Dec 1997 by Geert Uytterhoeven + * + * 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. + */ +/* TODO (roughly in order of priority): + * 16 bpp support + * crt support + * hw cursor support + */ + +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/io.h> +#include <linux/module.h> +#include <linux/kernel.h> + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/malloc.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/init.h> + +#include <video/fbcon.h> +#include <video/fbcon-mfb.h> +#include <video/fbcon-cfb8.h> + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/malloc.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/init.h> + +#include <video/fbcon.h> + +/* Register defines. The docs don't seem to provide nice mnemonic names + * so I made them up myself ... */ + +#define E1355_PANEL 0x02 +#define E1355_DISPLAY 0x0D +#define E1355_GPIO 0x20 +#define E1355_LUT_INDEX 0x24 +#define E1355_LUT_DATA 0x26 + +#ifdef CONFIG_SUPERH +/* tell me if your machine has a different base address .. */ +#define E1355_REG_BASE 0xB0000000 +#define E1355_FB_BASE 0xB0200000 + +static inline u8 e1355_read_reg(int index) +{ + return ctrl_inb(E1355_REG_BASE + index); +} + +static inline void e1355_write_reg(u8 data, int index) +{ + ctrl_outb(data, E1355_REG_BASE + index); +} + +static inline u16 e1355_read_reg16(int index) +{ + return e1355_read_reg(index) + (e1355_read_reg(index+1) << 8); +} + +static inline void e1355_write_reg16(u16 data, int index) +{ + e1355_write_reg((data&0xff), index); + e1355_write_reg(((data>>8)&0xff), index + 1); +} +#else +#error unknown architecture +#endif + +struct e1355fb_info { + struct fb_info_gen gen; +}; + +static int current_par_valid = 0; +static struct display disp; + +static struct fb_var_screeninfo default_var; + +int e1355fb_init(void); +int e1355fb_setup(char*); +static int e1355_encode_var(struct fb_var_screeninfo *var, const void *par, + struct fb_info_gen *info); +/* ------------------- chipset specific functions -------------------------- */ + + +static void e1355_detect(void) +{ + u8 rev; + + rev = e1355_read_reg(0x00); + + if ((rev & 0xfc) != 0x0c) { + printk(KERN_WARNING "Epson 1355 not detected\n"); + } + + e1355_encode_var(&default_var, NULL, NULL); +} + +struct e1355_par { + u32 xres; + u32 yres; + + int bpp; + int mem_bpp; + + u32 panel_xres; + u32 panel_yres; + + int panel_width; + int panel_ymul; +}; + +static int e1355_encode_fix(struct fb_fix_screeninfo *fix, + const void *raw_par, + struct fb_info_gen *info) +{ + const struct e1355_par *par = raw_par; + + memset(fix, 0, sizeof *fix); + + fix->type= FB_TYPE_PACKED_PIXELS; + + if (!par) + BUG(); + + if (par->bpp == 1) { + fix->visual = FB_VISUAL_MONO10; + } else if (par->bpp <= 8) { + fix->visual = FB_VISUAL_PSEUDOCOLOR; + } else { + fix->visual = FB_VISUAL_TRUECOLOR; + } + + return 0; +} + +static int e1355_set_bpp(struct e1355_par *par, int bpp) +{ + int code; + u8 disp; + u16 bytes_per_line; + + switch(bpp) { + case 1: + code = 0; break; + case 2: + code = 1; break; + case 4: + code = 2; break; + case 8: + code = 3; break; + case 16: + code = 5; break; + default: + return -EINVAL; break; + } + + disp = e1355_read_reg(E1355_DISPLAY); + disp &= ~0x1c; + disp |= code << 2; + e1355_write_reg(disp, E1355_DISPLAY); + + bytes_per_line = (par->xres * bpp) >> 3; + + e1355_write_reg16(bytes_per_line, 0x16); + + par->bpp = bpp; + + return 0; +} + +static int e1355_decode_var(const struct fb_var_screeninfo *var, + void *raw_par, + struct fb_info_gen *info) +{ + struct e1355_par *par = raw_par; + int ret; + + if (!par) + BUG(); + + /* + * Don't allow setting any of these yet: xres and yres don't + * make sense for LCD panels; xres_virtual and yres_virtual + * should be supported fine by our hardware though. + */ + if (var->xres != par->xres || + var->yres != par->yres || + var->xres != var->xres_virtual || + var->yres != var->yres_virtual || + var->xoffset != 0 || + var->yoffset != 0) + return -EINVAL; + + if(var->bits_per_pixel != par->bpp) { + ret = e1355_set_bpp(par, var->bits_per_pixel); + + if (ret) + goto out_err; + } + + return 0; + + out_err: + return ret; +} + +static void dump_panel_data(void) +{ + u8 panel = e1355_read_reg(E1355_PANEL); + int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } }; + + printk("%s %s %s panel, width %d bits\n", + panel & 2 ? "dual" : "single", + panel & 4 ? "color" : "mono", + panel & 1 ? "TFT" : "passive", + width[panel&1][(panel>>4)&3]); + + printk("resolution %d x %d\n", + (e1355_read_reg(0x04) + 1) * 8, + ((e1355_read_reg16(0x08) + 1) * (1 + ((panel & 3) == 2)))); +} + +static int e1355_bpp_to_var(int bpp, struct fb_var_screeninfo *var) +{ + switch(bpp) { + case 1: + case 2: + case 4: + case 8: + var->bits_per_pixel = bpp; + var->red.offset = var->green.offset = var->blue.offset = 0; + var->red.length = var->green.length = var->blue.length = bpp; + break; + case 16: + var->bits_per_pixel = 16; + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + break; + } + + return 0; +} + +static int e1355_encode_var(struct fb_var_screeninfo *var, const void *raw_par, + struct fb_info_gen *info) +{ + u8 panel, display; + u32 xres, xres_virtual, yres; + static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } }; + static int bpp_tab[8] = { 1, 2, 4, 8, 15, 16 }; + int bpp, hw_bpp; + int is_color, is_dual, is_tft; + int lcd_enabled, crt_enabled; + + panel = e1355_read_reg(E1355_PANEL); + display = e1355_read_reg(E1355_DISPLAY); + + is_color = (panel & 0x04) != 0; + is_dual = (panel & 0x02) != 0; + is_tft = (panel & 0x01) != 0; + + bpp = bpp_tab[(display>>2)&7]; + e1355_bpp_to_var(bpp, var); + + crt_enabled = (display & 0x02) != 0; + lcd_enabled = (display & 0x02) != 0; + + hw_bpp = width[is_tft][(panel>>4)&3]; + + xres = e1355_read_reg(0x04) + 1; + yres = e1355_read_reg16(0x08) + 1; + + xres *= 8; + /* talk about weird hardware .. */ + yres *= (is_dual && !crt_enabled) ? 2 : 1; + + xres_virtual = e1355_read_reg16(0x16); + /* it's in 2-byte words initially */ + xres_virtual *= 16; + xres_virtual /= var->bits_per_pixel; + + var->xres = xres; + var->yres = yres; + var->xres_virtual = xres_virtual; + var->yres_virtual = yres; + + var->xoffset = var->yoffset = 0; + + var->grayscale = !is_color; + + return 0; +} + +#define is_dual(panel) (((panel)&3)==2) + +static void get_panel_data(struct e1355_par *par) +{ + u8 panel; + int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } }; + + panel = e1355_read_reg(E1355_PANEL); + + par->panel_width = width[panel&1][(panel>>4)&3]; + par->panel_xres = (e1355_read_reg(0x04) + 1) * 8; + par->panel_ymul = is_dual(panel) ? 2 : 1; + par->panel_yres = ((e1355_read_reg16(0x08) + 1) + * par->panel_ymul); +} + +static void e1355_get_par(void *raw_par, struct fb_info_gen *info) +{ + struct e1355_par *par = raw_par; + + get_panel_data(par); +} + +static void e1355_set_par(const void *par, struct fb_info_gen *info) +{ +} + +static int e1355_getcolreg(unsigned regno, unsigned *red, unsigned *green, + unsigned *blue, unsigned *transp, + struct fb_info *info) +{ + u8 r, g, b; + + e1355_write_reg(regno, E1355_LUT_INDEX); + r = e1355_read_reg(E1355_LUT_DATA); + g = e1355_read_reg(E1355_LUT_DATA); + b = e1355_read_reg(E1355_LUT_DATA); + + *red = r << 8; + *green = g << 8; + *blue = b << 8; + + return 0; +} + +static int e1355_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + u8 r = (red >> 8) & 0xf0; + u8 g = (green>>8) & 0xf0; + u8 b = (blue>> 8) & 0xf0; + + e1355_write_reg(regno, E1355_LUT_INDEX); + e1355_write_reg(r, E1355_LUT_DATA); + e1355_write_reg(g, E1355_LUT_DATA); + e1355_write_reg(b, E1355_LUT_DATA); + + return 0; +} + +static int e1355_pan_display(const struct fb_var_screeninfo *var, + struct fb_info_gen *info) +{ + BUG(); + + return -EINVAL; +} + +/* + * The AERO_HACKS parts disable/enable the backlight on the Compaq Aero 8000. + * I'm not sure they aren't dangerous to the hardware, so be warned. + */ +#define AERO_HACKS + +static int e1355_blank(int blank_mode, struct fb_info_gen *info) +{ + u8 disp; + + switch (blank_mode) { + case VESA_NO_BLANKING: + disp = e1355_read_reg(E1355_DISPLAY); + disp |= 1; + e1355_write_reg(disp, E1355_DISPLAY); + +#ifdef AERO_HACKS + e1355_write_reg(0x6, 0x20); +#endif + break; + + case VESA_VSYNC_SUSPEND: + case VESA_HSYNC_SUSPEND: + case VESA_POWERDOWN: + disp = e1355_read_reg(E1355_DISPLAY); + disp &= ~1; + e1355_write_reg(disp, E1355_DISPLAY); + +#ifdef AERO_HACKS + e1355_write_reg(0x0, 0x20); +#endif + break; + + default: + return -EINVAL; + } + + return 0; +} + +static struct display_switch e1355_dispsw; + +static void e1355_set_disp(const void *unused, struct display *disp, + struct fb_info_gen *info) +{ + struct display_switch *d; + + disp->screen_base = (void *)E1355_FB_BASE; + disp->dispsw = &e1355_dispsw; + + switch(disp->var.bits_per_pixel) { +#ifdef FBCON_HAS_MFB + case 1: + d = &fbcon_mfb; break; +#endif +#ifdef FBCON_HAS_CFB8 + case 8: + d = &fbcon_cfb8; break; +#endif + default: + BUG(); break; + } + + memcpy(&e1355_dispsw, d, sizeof *d); + + /* reading is terribly slow for us */ +#if 0 /* XXX: need to work out why this doesn't work */ + e1355_dispsw.bmove = fbcon_redraw_bmove; +#endif +} + +/* ------------ Interfaces to hardware functions ------------ */ + + +struct fbgen_hwswitch e1355_switch = { + detect: e1355_detect, + encode_fix: e1355_encode_fix, + decode_var: e1355_decode_var, + encode_var: e1355_encode_var, + get_par: e1355_get_par, + set_par: e1355_set_par, + getcolreg: e1355_getcolreg, + setcolreg: e1355_setcolreg, + pan_display: e1355_pan_display, + blank: e1355_blank, + set_disp: e1355_set_disp, +}; + + +/* ------------ Hardware Independent Functions ------------ */ + + +static struct fb_ops e1355fb_ops = { + owner: THIS_MODULE, + fb_get_fix: fbgen_get_fix, + fb_get_var: fbgen_get_var, + fb_set_var: fbgen_set_var, + fb_get_cmap: fbgen_get_cmap, + fb_set_cmap: fbgen_set_cmap, + fb_pan_display: fbgen_pan_display, +}; + +static struct e1355fb_info fb_info; + +int __init e1355fb_setup(char *str) +{ + return 0; +} + +static void disable_hw_cursor(void) +{ + u8 curs; + + curs = e1355_read_reg(0x27); + curs &= ~0xc0; + e1355_write_reg(curs, 0x27); +} + +int __init e1355fb_init(void) +{ + disable_hw_cursor(); + + fb_info.gen.fbhw = &e1355_switch; + fb_info.gen.fbhw->detect(); + strcpy(fb_info.gen.info.modename, "SED1355"); + fb_info.gen.info.changevar = NULL; + fb_info.gen.info.node = -1; + fb_info.gen.info.fbops = &e1355fb_ops; + fb_info.gen.info.disp = &disp; + fb_info.gen.parsize = sizeof(struct e1355_par); + fb_info.gen.info.switch_con = &fbgen_switch; + fb_info.gen.info.updatevar = &fbgen_update_var; + fb_info.gen.info.blank = &fbgen_blank; + fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT; + /* This should give a reasonable default video mode */ + fbgen_get_var(&disp.var, -1, &fb_info.gen.info); + fbgen_do_set_var(&disp.var, 1, &fb_info.gen); + fbgen_set_disp(-1, &fb_info.gen); + if (disp.var.bits_per_pixel > 1) + fbgen_install_cmap(0, &fb_info.gen); + if (register_framebuffer(&fb_info.gen.info) < 0) + return -EINVAL; + printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node), + fb_info.gen.info.modename); + + return 0; +} + + + /* + * Cleanup + */ + +void e1355fb_cleanup(struct fb_info *info) +{ + /* + * If your driver supports multiple boards, you should unregister and + * clean up all instances. + */ + + unregister_framebuffer(info); + /* ... */ +} + diff -urNx CVS linuxsh/kernel/drivers/video/fbmem.c linux-aero/drivers/video/fbmem.c --- linuxsh/kernel/drivers/video/fbmem.c Sun Dec 24 03:44:45 2000 +++ linux-aero/drivers/video/fbmem.c Mon Dec 25 02:59:52 2000 @@ -115,7 +115,9 @@ extern int sisfb_setup(char*); extern int stifb_init(void); extern int stifb_setup(char*); - +extern int e1355fb_init(void); +extern int e1355fb_setup(char*); + static struct { const char *name; int (*init)(void); @@ -190,6 +192,9 @@ #endif #ifdef CONFIG_FB_SIS { "sisfb", sisfb_init, sisfb_setup }, +#endif +#ifdef CONFIG_FB_E1355 + { "e1355fb", e1355fb_init, e1355fb_setup }, #endif /* diff -urNx CVS linuxsh/kernel/include/asm-sh/ec3104.h linux-aero/include/asm-sh/ec3104.h --- linuxsh/kernel/include/asm-sh/ec3104.h Wed Dec 31 16:00:00 1969 +++ linux-aero/include/asm-sh/ec3104.h Mon Dec 25 02:59:52 2000 @@ -0,0 +1,43 @@ +#ifndef __ASM_EC3104_H +#define __ASM_EC3104_H + + +/* + * Most of the register set is at 0xb0ec0000 - 0xb0ecffff. + * + * as far as I've figured it out the register map is: + * 0xb0ec0000 - id string + * 0xb0ec0XXX - power management + * 0xb0ec1XXX - interrupt control + * 0xb0ec3XXX - ps2 port (touch pad on aero 8000) + * 0xb0ec6XXX - i2c + * 0xb0ec7000 - first serial port (proprietary connector on aero 8000) + * 0xb0ec8000 - second serial port + * 0xb0ec9000 - third serial port + * 0xb0eca000 - fourth serial port (keyboard controller on aero 8000) + * 0xb0eccXXX - GPIO + * 0xb0ecdXXX - GPIO + */ + +#define EC3104_BASE 0xb0ec0000 + +#define EC3104_SER4_DATA (EC3104_BASE+0xa000) +#define EC3104_SER4_IIR (EC3104_BASE+0xa008) +#define EC3104_SER4_MCR (EC3104_BASE+0xa010) +#define EC3104_SER4_LSR (EC3104_BASE+0xa014) +#define EC3104_SER4_MSR (EC3104_BASE+0xa018) + +/* + * our ISA bus. this seems to be real ISA. + */ +#define EC3104_ISA_BASE 0xa5000000 + +#define EC3104_IRQ 11 +#define EC3104_IRQBASE 64 + +#define EC3104_IRQ_SER1 EC3104_IRQBASE + 7 +#define EC3104_IRQ_SER2 EC3104_IRQBASE + 8 +#define EC3104_IRQ_SER3 EC3104_IRQBASE + 9 +#define EC3104_IRQ_SER4 EC3104_IRQBASE + 10 + +#endif /* __ASM_EC3104_H */ diff -urNx CVS linuxsh/kernel/include/asm-sh/io.h linux-aero/include/asm-sh/io.h --- linuxsh/kernel/include/asm-sh/io.h Fri Dec 8 13:32:56 2000 +++ linux-aero/include/asm-sh/io.h Mon Dec 25 03:12:47 2000 @@ -115,6 +115,8 @@ # include <asm/io_se.h> # elif defined(CONFIG_SH_FOOBAR) # include <asm/io_hd64465.h> +# elif defined(CONFIG_SH_EC3104) +# include <asm/io_ec3104.h> # elif defined(CONFIG_SH_UNKNOWN) # include <asm/io_unknown.h> # else diff -urNx CVS linuxsh/kernel/include/asm-sh/io_ec3104.h linux-aero/include/asm-sh/io_ec3104.h --- linuxsh/kernel/include/asm-sh/io_ec3104.h Wed Dec 31 16:00:00 1969 +++ linux-aero/include/asm-sh/io_ec3104.h Mon Dec 25 03:12:47 2000 @@ -0,0 +1,54 @@ +#ifndef _ASM_SH_IO_EC3104_H +#define _ASM_SH_IO_EC3104_H + +#include <asm/io_generic.h> +#include <linux/types.h> + +extern unsigned char ec3104_inb(unsigned long port); +extern unsigned short ec3104_inw(unsigned long port); +extern unsigned long ec3104_inl(unsigned long port); + +extern void ec3104_outb(unsigned char value, unsigned long port); +extern void ec3104_outw(unsigned short value, unsigned long port); +extern void ec3104_outl(unsigned long value, unsigned long port); + +extern int ec3104_irq_demux(int irq); + +#ifdef __WANT_IO_DEF + +# define __inb ec3104_inb +# define __inw ec3104_inw +# define __inl ec3104_inl +# define __outb ec3104_outb +# define __outw ec3104_outw +# define __outl ec3104_outl + +# define __inb_p ec3104_inb +# define __inw_p ec3104_inw +# define __inl_p ec3104_inl +# define __outb_p ec3104_outb +# define __outw_p ec3104_outw +# define __outl_p ec3104_outl + +# define __insb generic_insb +# define __insw generic_insw +# define __insl generic_insl +# define __outsb generic_outsb +# define __outsw generic_outsw +# define __outsl generic_outsl + +# define __readb generic_readb +# define __readw generic_readw +# define __readl generic_readl +# define __writeb generic_writeb +# define __writew generic_writew +# define __writel generic_writel + +# define __isa_port2addr generic_isa_port2addr +# define __ioremap generic_ioremap +# define __ioremap_nocache generic_ioremap_nocache +# define __iounmap generic_iounmap + +#endif + +#endif /* _ASM_SH_IO_EC3104_H */ diff -urNx CVS linuxsh/kernel/include/asm-sh/irq.h linux-aero/include/asm-sh/irq.h --- linuxsh/kernel/include/asm-sh/irq.h Fri Dec 8 13:32:57 2000 +++ linux-aero/include/asm-sh/irq.h Mon Dec 25 03:12:44 2000 @@ -85,6 +85,8 @@ # if defined(__SH4__) # ifdef CONFIG_HD64465 # define NR_IRQS 80 /* HD64465_IRQBASE+16, see hd64465.h */ +# elif defined (CONFIG_SH_EC3104) +# define NR_IRQS 96 # else /* * 48 = 32+16 @@ -208,6 +210,11 @@ extern int hd64465_irq_demux(int irq); #define irq_demux(irq) hd64465_irq_demux(irq) + +#elif defined(CONFIG_SH_EC3104) + +extern int ec3104_irq_demux(int irq); +#define irq_demux ec3104_irq_demux #else diff -urNx CVS linuxsh/kernel/include/asm-sh/keyboard-ec3104.h linux-aero/include/asm-sh/keyboard-ec3104.h --- linuxsh/kernel/include/asm-sh/keyboard-ec3104.h Wed Dec 31 16:00:00 1969 +++ linux-aero/include/asm-sh/keyboard-ec3104.h Mon Dec 25 03:51:23 2000 @@ -0,0 +1,17 @@ +extern unsigned char ec3104_kbd_sysrq_xlate[]; +extern int ec3104_kbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int ec3104_kbd_getkeycode(unsigned int scancode); +extern int ec3104_kbd_translate(unsigned char, unsigned char *, char); +extern char ec3104_kbd_unexpected_up(unsigned char); +extern void ec3104_kbd_leds(unsigned char); +extern void ec3104_kbd_init_hw(void); + +#define SYSRQ_KEY 0x54 + +#define kbd_sysrq_xlate ec3104_kbd_sysrq_xlate +#define kbd_setkeycode ec3104_kbd_setkeycode +#define kbd_getkeycode ec3104_kbd_getkeycode +#define kbd_translate ec3104_kbd_translate +#define kbd_unexpected_up ec3104_kbd_unexpected_up +#define kbd_leds ec3104_kbd_leds +#define kbd_init_hw ec3104_kbd_init_hw diff -urNx CVS linuxsh/kernel/include/asm-sh/machvec.h linux-aero/include/asm-sh/machvec.h --- linuxsh/kernel/include/asm-sh/machvec.h Fri Dec 8 13:32:58 2000 +++ linux-aero/include/asm-sh/machvec.h Mon Dec 25 03:12:43 2000 @@ -13,6 +13,8 @@ #include <linux/config.h> #include <linux/types.h> +struct timeval; + struct sh_machine_vector { const char *mv_name; @@ -61,6 +63,9 @@ void (*mv_heartbeat)(void); + void (*mv_rtc_gettimeofday)(struct timeval *tv); + int (*mv_rtc_settimeofday)(const struct timeval *tv); + unsigned int mv_hw_se : 1; unsigned int mv_hw_hp600 : 1; unsigned int mv_hw_hp620 : 1; @@ -116,6 +121,11 @@ # define MACH_HD64465 1 # else # define MACH_HD64465 0 +# endif +# ifdef CONFIG_SH_EC3104 +# define MACH_EC3104 1 +# else +# define MACH_EC3104 0 # endif #endif diff -urNx CVS linuxsh/kernel/include/asm-sh/rtc.h linux-aero/include/asm-sh/rtc.h --- linuxsh/kernel/include/asm-sh/rtc.h Wed Dec 31 16:00:00 1969 +++ linux-aero/include/asm-sh/rtc.h Mon Dec 25 03:47:33 2000 @@ -0,0 +1,12 @@ +#ifndef _ASM_RTC_H +#define _ASM_RTC_H + +#include <asm/machvec.h> + +#define rtc_gettimeofday sh_mv.mv_rtc_gettimeofday +#define rtc_settimeofday sh_mv.mv_rtc_settimeofday + +extern void sh_rtc_gettimeofday(struct timeval *tv); +extern int sh_rtc_settimeofday(const struct timeval *tv); + +#endif /* _ASM_RTC_H */ diff -urNx CVS linuxsh/kernel/include/asm-sh/serial-ec3104.h linux-aero/include/asm-sh/serial-ec3104.h --- linuxsh/kernel/include/asm-sh/serial-ec3104.h Wed Dec 31 16:00:00 1969 +++ linux-aero/include/asm-sh/serial-ec3104.h Mon Dec 25 02:59:52 2000 @@ -0,0 +1,24 @@ +#include <asm/ec3104.h> +/* Naturally we don't know the exact value but 115200 baud has a divisor + * of 9 and 19200 baud has a divisor of 52, so this seems like a good + * guess. */ +#define BASE_BAUD (16800000 / 16) + +#define RS_TABLE_SIZE 3 + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + +/* there is a fourth serial port with the expected values as well, but + * it's got the keyboard controller behind it so we can't really use it + * (without moving the keyboard driver to userspace, which doesn't sound + * like a very good idea) */ +#define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x11C00, EC3104_IRQBASE+7, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x12000, EC3104_IRQBASE+8, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x12400, EC3104_IRQBASE+9, STD_COM_FLAGS }, /* ttyS2 */ + +#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS + +/* XXX: This should be moved ino irq.h */ +#define irq_cannonicalize(x) (x) diff -urNx CVS linuxsh/kernel/include/asm-sh/keyboard.h linux-aero/include/asm-sh/keyboard.h --- linuxsh/kernel/include/asm-sh/keyboard.h Mon Dec 25 04:47:33 2000 +++ linux-aero/include/asm-sh/keyboard.h Mon Dec 25 03:51:25 2000 @@ -4,8 +4,12 @@ * $Id: keyboard.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $ */ +#include <linux/config.h> #include <asm/machvec.h> +#ifdef CONFIG_SH_EC3104 +#include <asm/keyboard-ec3104.h> +#else static __inline__ int kbd_setkeycode(unsigned int scancode, unsigned int keycode) { @@ -42,4 +46,5 @@ } } +#endif #endif diff -urNx CVS linuxsh/kernel/include/asm-sh/serial.h linux-aero/include/asm-sh/serial.h --- linuxsh/kernel/include/asm-sh/serial.h Fri Dec 8 13:32:58 2000 +++ linux-aero/include/asm-sh/serial.h Mon Dec 25 03:15:02 2000 @@ -7,6 +7,13 @@ #ifndef _ASM_SERIAL_H #define _ASM_SERIAL_H +#include <linux/config.h> +#include <linux/kernel.h> + +#ifdef CONFIG_SH_EC3104 +#include <asm/serial-ec3104.h> +#else + /* * This assumes you have a 1.8432 MHz clock for your UART. * @@ -30,4 +37,5 @@ /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) +#endif #endif /* _ASM_SERIAL_H */ Those two should be obvious: diff -urNx CVS linuxsh/kernel/include/asm-sh/system.h linux-aero/include/asm-sh/system.h --- linuxsh/kernel/include/asm-sh/system.h Fri Dec 8 13:33:00 2000 +++ linux-aero/include/asm-sh/system.h Mon Dec 25 02:59:52 2000 @@ -6,6 +6,7 @@ */ #include <linux/config.h> +#include <linux/kernel.h> /* * switch_to() should switch tasks to task nr n, first diff -urNx CVS linuxsh/kernel/include/asm-sh/uaccess.h linux-aero/include/asm-sh/uaccess.h --- linuxsh/kernel/include/asm-sh/uaccess.h Fri Dec 8 13:33:02 2000 +++ linux-aero/include/asm-sh/uaccess.h Mon Dec 25 03:12:44 2000 @@ -66,7 +66,7 @@ * They automatically use the right size if we just have the right * pointer type ... * - * As MIPS uses the same address space for kernel and user data, we + * As SuperH uses the same address space for kernel and user data, we * can just do these as direct assignments. * * Careful to not |