diff options
| -rw-r--r-- | target/linux/sibyte/Makefile | 4 | ||||
| -rw-r--r-- | target/linux/sibyte/config-default (renamed from target/linux/sibyte/config-2.6.21) | 171 | ||||
| -rw-r--r-- | target/linux/sibyte/patches/000-DUART.patch | 1025 | 
3 files changed, 83 insertions, 1117 deletions
| diff --git a/target/linux/sibyte/Makefile b/target/linux/sibyte/Makefile index 52728da19..74c15cb32 100644 --- a/target/linux/sibyte/Makefile +++ b/target/linux/sibyte/Makefile @@ -8,10 +8,10 @@ include $(TOPDIR)/rules.mk  ARCH:=mips  BOARD:=sibyte -BOARDNAME:=SiByte MIPS +BOARDNAME:=Broadcom/SiByte SB-1  FEATURES:=broken -LINUX_VERSION:=2.6.21.5 +LINUX_VERSION:=2.6.24  include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/sibyte/config-2.6.21 b/target/linux/sibyte/config-default index 1c4f3e1d2..4cf2ac57e 100644 --- a/target/linux/sibyte/config-2.6.21 +++ b/target/linux/sibyte/config-default @@ -1,22 +1,26 @@  # CONFIG_32BIT is not set  CONFIG_64BIT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y  # CONFIG_ARPD is not set  # CONFIG_ATM is not set  # CONFIG_ATMEL is not set -# CONFIG_AU1000_UART is not set  CONFIG_BASE_SMALL=0 +# CONFIG_BCM47XX is not set  CONFIG_BINFMT_ELF32=y -CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BITREVERSE=y +CONFIG_BLOCK_COMPAT=y  # CONFIG_BONDING is not set  CONFIG_BOOT_ELF32=y +CONFIG_BROADCOM_PHY=y  # CONFIG_BSD_DISKLABEL is not set  # CONFIG_BSD_PROCESS_ACCT is not set  # CONFIG_BT is not set -CONFIG_BUILD_ELF64=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CEVT_SB1250=y +CONFIG_CFE=y  # CONFIG_CIFS_STATS is not set  # CONFIG_CLS_U32_MARK is not set  # CONFIG_CLS_U32_PERF is not set @@ -24,12 +28,12 @@ CONFIG_COMPAT=y  # CONFIG_COMPUTONE is not set  # CONFIG_CONFIGFS_FS is not set  CONFIG_CONNECTOR=m -CONFIG_CPUSETS=y  CONFIG_CPU_BIG_ENDIAN=y  CONFIG_CPU_HAS_LLSC=y  CONFIG_CPU_HAS_PREFETCH=y  CONFIG_CPU_HAS_SYNC=y  # CONFIG_CPU_LITTLE_ENDIAN is not set +# CONFIG_CPU_LOONGSON2 is not set  # CONFIG_CPU_MIPS32_R1 is not set  # CONFIG_CPU_MIPS32_R2 is not set  # CONFIG_CPU_MIPS64_R1 is not set @@ -50,128 +54,105 @@ CONFIG_CPU_SB1=y  # CONFIG_CPU_SB1_PASS_2_112x is not set  # CONFIG_CPU_SB1_PASS_2_1250 is not set  # CONFIG_CPU_SB1_PASS_2_2 is not set -# CONFIG_CPU_SB1_PASS_3 is not set -CONFIG_CPU_SB1_PASS_4=y +CONFIG_CPU_SB1_PASS_3=y +# CONFIG_CPU_SB1_PASS_4 is not set  CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y  CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y  CONFIG_CPU_SUPPORTS_HIGHMEM=y  # CONFIG_CPU_TX39XX is not set  # CONFIG_CPU_TX49XX is not set  # CONFIG_CPU_VR41XX is not set +# CONFIG_CRYPTO_HW is not set +CONFIG_CSRC_SB1250=y  # CONFIG_CYCLADES is not set -# CONFIG_DDB5074 is not set -# CONFIG_DDB5476 is not set -# CONFIG_DDB5477 is not set +CONFIG_DEVPORT=y  # CONFIG_DIGIEPCA is not set  # CONFIG_DM9000 is not set  CONFIG_DMA_COHERENT=y +# CONFIG_E1000E is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_FIXED_PHY is not set +CONFIG_FS_POSIX_ACL=y  CONFIG_FW_LOADER=m -# CONFIG_GEN_RTC is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y  # CONFIG_HERMES is not set -# CONFIG_HID is not set +CONFIG_HID_SUPPORT=y  # CONFIG_HOSTAP_PCI is not set  # CONFIG_HOSTAP_PLX is not set  CONFIG_HW_HAS_PCI=y  CONFIG_HW_RANDOM=m  CONFIG_HZ=250  # CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_1024 is not set  CONFIG_HZ_250=y -# CONFIG_HZ_256 is not set -# CONFIG_HZ_48 is not set  # CONFIG_I2C is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set  # CONFIG_IDE is not set -# CONFIG_IKCONFIG is not set -# CONFIG_INET6_TUNNEL is not set  CONFIG_INITRAMFS_ROOT_GID=0  CONFIG_INITRAMFS_ROOT_UID=0  CONFIG_INITRAMFS_SOURCE="../root"  CONFIG_INPUT=m -# CONFIG_IOSCHED_NOOP is not set -# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP1000 is not set  # CONFIG_IP6_NF_MATCH_FRAG is not set  # CONFIG_IP6_NF_MATCH_HL is not set  # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -CONFIG_IP6_NF_MATCH_MULTIPORT=m  # CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_POLICY is not set  # CONFIG_IP6_NF_MATCH_RT is not set  # CONFIG_IP6_NF_TARGET_HL is not set  # CONFIG_IP6_NF_TARGET_LOG is not set  # CONFIG_IPW2100 is not set  # CONFIG_IPW2200 is not set -# CONFIG_IP_DCCP is not set  # CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set  # CONFIG_IP_NF_MATCH_ADDRTYPE is not set -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_DSCP=m -# CONFIG_IP_NF_MATCH_HASHLIMIT is not set -CONFIG_IP_NF_MATCH_MULTIPORT=m -# CONFIG_IP_NF_MATCH_POLICY is not set -CONFIG_IP_NF_TARGET_DSCP=m  # CONFIG_IP_NF_TARGET_LOG is not set  # CONFIG_IP_NF_TARGET_NETMAP is not set  # CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set  # CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IRQ_CPU=y  # CONFIG_ISI is not set -# CONFIG_LIBCRC32C is not set +# CONFIG_LEDS_ALIX is not set +# CONFIG_LEMOTE_FULONG is not set  # CONFIG_LLC2 is not set -CONFIG_LOCK_KERNEL=y  CONFIG_LOG_BUF_SHIFT=15  # CONFIG_MACH_ALCHEMY is not set  # CONFIG_MACH_DECSTATION is not set  # CONFIG_MACH_JAZZ is not set  # CONFIG_MACH_VR41XX is not set +# CONFIG_MDIO_BITBANG is not set  CONFIG_MINI_FO=m  CONFIG_MIPS=y  CONFIG_MIPS32_COMPAT=y  # CONFIG_MIPS32_N32 is not set  CONFIG_MIPS32_O32=y  # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_BOSPORUS is not set  # CONFIG_MIPS_COBALT is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set  CONFIG_MIPS_L1_CACHE_SHIFT=5  # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_MIPS_MT is not set -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set  # CONFIG_MIPS_SEAD is not set  # CONFIG_MIPS_SIM is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set -# CONFIG_MOMENCO_OCELOT_G is not set  # CONFIG_MOXA_INTELLIO is not set  # CONFIG_MOXA_SMARTIO is not set  # CONFIG_MOXA_SMARTIO_NEW is not set  CONFIG_MTD=y  # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_BLKMTD is not set +CONFIG_MTD_BLKDEVS=y  CONFIG_MTD_BLOCK=y  # CONFIG_MTD_BLOCK2MTD is not set  CONFIG_MTD_CFI=y  # CONFIG_MTD_CFI_ADV_OPTIONS is not set  CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_AMDSTD_RETRY=0  CONFIG_MTD_CFI_I1=y  CONFIG_MTD_CFI_I2=y  # CONFIG_MTD_CFI_I4 is not set @@ -196,104 +177,114 @@ CONFIG_MTD_MAP_BANK_WIDTH_2=y  CONFIG_MTD_MAP_BANK_WIDTH_4=y  # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set  # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set  # CONFIG_MTD_ONENAND is not set  CONFIG_MTD_PARTITIONS=y  # CONFIG_MTD_PCI is not set  # CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_START=0x8000000  # CONFIG_MTD_PLATRAM is not set  # CONFIG_MTD_PMC551 is not set  # CONFIG_MTD_RAM is not set  # CONFIG_MTD_REDBOOT_PARTS is not set  # CONFIG_MTD_ROM is not set  # CONFIG_MTD_SLRAM is not set -# CONFIG_NET_DIVERT is not set +CONFIG_NETDEV_1000=y  # CONFIG_NET_EMATCH is not set  # CONFIG_NET_IPGRE_BROADCAST is not set  # CONFIG_NET_PCI is not set  # CONFIG_NET_PKTGEN is not set -CONFIG_NET_SB1250_MAC=y  # CONFIG_NET_SCH_NETEM is not set  # CONFIG_NET_VENDOR_3COM is not set -CONFIG_NETDEV_1000=y -CONFIG_NR_CPUS=2 -# CONFIG_NTFS_FS is not set +# CONFIG_NO_IOPORT is not set  # CONFIG_N_HDLC is not set -CONFIG_OBSOLETE_INTERMODULE=y -CONFIG_OBSOLETE_MODPARM=y  # CONFIG_PAGE_SIZE_16KB is not set  CONFIG_PAGE_SIZE_4KB=y  # CONFIG_PAGE_SIZE_64KB is not set  # CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PCMCIA is not set -# CONFIG_PCCARD is not set -# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_DOMAINS=y +CONFIG_PHYLIB=y +# CONFIG_PMC_MSP is not set  # CONFIG_PMC_YOSEMITE is not set  # CONFIG_PNX8550_JBS is not set  # CONFIG_PNX8550_STB810 is not set  # CONFIG_PPP_MULTILINK is not set  # CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PREEMPT_BKL is not set  # CONFIG_PRISM54 is not set  # CONFIG_PROC_KCORE is not set -# CONFIG_RELAYFS_FS is not set +# CONFIG_QSEMI_PHY is not set +CONFIG_RESOURCES_64BIT=y  # CONFIG_RIO is not set +# CONFIG_RISCOM8 is not set  # CONFIG_ROCKETPORT is not set -# CONFIG_ROMFS_FS is not set  # CONFIG_RTC is not set +CONFIG_RTC_LIB=y  CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_SB1250_MAC=y  # CONFIG_SB1XXX_CORELIS is not set  # CONFIG_SB1_CERR_STALL is not set  # CONFIG_SB1_CEX_ALWAYS_FATAL is not set +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y  # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set  # CONFIG_SERIAL_8250 is not set  CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_SB1250_DUART=y +CONFIG_SERIAL_SB1250_DUART_CONSOLE=y  # CONFIG_SGI_IP22 is not set  # CONFIG_SGI_IP27 is not set  # CONFIG_SGI_IP32 is not set +CONFIG_SIBYTE_BCM1125H=y +CONFIG_SIBYTE_BCM112X=y  # CONFIG_SIBYTE_BIGSUR is not set  # CONFIG_SIBYTE_BUS_WATCHER is not set  # CONFIG_SIBYTE_CARMEL is not set  CONFIG_SIBYTE_CFE=y -CONFIG_SIBYTE_CFE_CONSOLE=y +# CONFIG_SIBYTE_CFE_CONSOLE is not set  # CONFIG_SIBYTE_CRHINE is not set  # CONFIG_SIBYTE_CRHONE is not set  # CONFIG_SIBYTE_DMA_PAGEOPS is not set +CONFIG_SIBYTE_ENABLE_LDT_IF_PCI=y  CONFIG_SIBYTE_HAS_LDT=y +CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y  # CONFIG_SIBYTE_LITTLESUR is not set  # CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_RHONE is not set -CONFIG_SIBYTE_SB1250=y -CONFIG_SIBYTE_SB1250_DUART=y -CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y -# CONFIG_SIBYTE_SB1250_PROF is not set +CONFIG_SIBYTE_RHONE=y  CONFIG_SIBYTE_SB1xxx_SOC=y  # CONFIG_SIBYTE_SENTOSA is not set -CONFIG_SIBYTE_SWARM=y +# CONFIG_SIBYTE_SWARM is not set  # CONFIG_SIBYTE_TBPROF is not set  # CONFIG_SIMULATION is not set -CONFIG_SMP=y +CONFIG_SLABINFO=y +# CONFIG_SMSC_PHY is not set  # CONFIG_SOUND is not set  # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set  # CONFIG_SPECIALIX is not set +CONFIG_SSB_POSSIBLE=y  # CONFIG_STALDRV is not set -CONFIG_STOP_MACHINE=y  CONFIG_SWAP_IO_SPACE=y  # CONFIG_SX is not set  # CONFIG_SYNCLINKMP is not set  # CONFIG_SYNCLINK_GT is not set +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y  CONFIG_SYS_HAS_CPU_SB1=y +CONFIG_SYS_HAS_EARLY_PRINTK=y  CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y  CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y  CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y  CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -# CONFIG_TELCLOCK is not set +CONFIG_TICK_ONESHOT=y  # CONFIG_TOSHIBA_JMR3927 is not set  # CONFIG_TOSHIBA_RBTX4927 is not set  # CONFIG_TOSHIBA_RBTX4938 is not set -# CONFIG_UNUSED_SYMBOLS is not set  # CONFIG_USB is not set +# CONFIG_USER_NS is not set +# CONFIG_VGASTATE is not set  # CONFIG_WATCHDOG is not set +CONFIG_WEAK_ORDERING=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/sibyte/patches/000-DUART.patch b/target/linux/sibyte/patches/000-DUART.patch deleted file mode 100644 index 468d9dfac..000000000 --- a/target/linux/sibyte/patches/000-DUART.patch +++ /dev/null @@ -1,1025 +0,0 @@ -diff -Nur linux-2.6.21.1/drivers/char/Kconfig linux-2.6.21.1-owrt/drivers/char/Kconfig ---- linux-2.6.21.1/drivers/char/Kconfig	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1-owrt/drivers/char/Kconfig	2007-05-24 22:28:54.000000000 +0200 -@@ -386,6 +386,14 @@ - 	  If you have an Alchemy AU1000 processor (MIPS based) and you want - 	  to use a console on a serial port, say Y.  Otherwise, say N. -  -+config SIBYTE_SB1250_DUART -+	bool "Support for BCM1xxx onchip DUART" -+	depends on MIPS && SIBYTE_SB1xxx_SOC=y -+ -+config SIBYTE_SB1250_DUART_CONSOLE -+	bool "Console on BCM1xxx DUART" -+	depends on SIBYTE_SB1250_DUART -+ - config SERIAL_DEC - 	bool "DECstation serial support" - 	depends on MACH_DECSTATION -diff -Nur linux-2.6.21.1/drivers/char/Makefile linux-2.6.21.1-owrt/drivers/char/Makefile ---- linux-2.6.21.1/drivers/char/Makefile	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1-owrt/drivers/char/Makefile	2007-05-24 22:32:31.000000000 +0200 -@@ -32,6 +32,7 @@ - obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o - obj-$(CONFIG_MOXA_SMARTIO)	+= mxser.o - obj-$(CONFIG_MOXA_SMARTIO_NEW)	+= mxser_new.o -+obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o - obj-$(CONFIG_COMPUTONE)		+= ip2/ - obj-$(CONFIG_RISCOM8)		+= riscom8.o - obj-$(CONFIG_ISI)		+= isicom.o -diff -Nur linux-2.6.21.1/drivers/char/sb1250_duart.c linux-2.6.21.1-owrt/drivers/char/sb1250_duart.c ---- linux-2.6.21.1/drivers/char/sb1250_duart.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1-owrt/drivers/char/sb1250_duart.c	2007-05-24 22:10:12.000000000 +0200 -@@ -0,0 +1,979 @@ -+/* -+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. -+ */ -+ -+/* -+ * Driver support for the on-chip sb1250 dual-channel serial port, -+ * running in asynchronous mode.  Also, support for doing a serial console -+ * on one of those ports -+ */ -+#include <linux/types.h> -+#include <linux/kernel.h> -+#include <linux/serial.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/console.h> -+#include <linux/kdev_t.h> -+#include <linux/major.h> -+#include <linux/termios.h> -+#include <linux/spinlock.h> -+#include <linux/irq.h> -+#include <linux/errno.h> -+#include <linux/tty.h> -+#include <linux/sched.h> -+#include <linux/tty_flip.h> -+#include <linux/timer.h> -+#include <linux/init.h> -+#include <linux/mm.h> -+#include <asm/delay.h> -+#include <asm/io.h> -+#include <asm/uaccess.h> -+#include <asm/sibyte/swarm.h> -+#include <asm/sibyte/sb1250.h> -+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) -+#include <asm/sibyte/bcm1480_regs.h> -+#include <asm/sibyte/bcm1480_int.h> -+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) -+#include <asm/sibyte/sb1250_regs.h> -+#include <asm/sibyte/sb1250_int.h> -+#else -+#error invalid SiByte UART configuation -+#endif -+#include <asm/sibyte/sb1250_uart.h> -+#include <asm/war.h> -+ -+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) -+#define UNIT_CHANREG(n,reg)	A_BCM1480_DUART_CHANREG((n),(reg)) -+#define UNIT_IMRREG(n)		A_BCM1480_DUART_IMRREG(n) -+#define UNIT_INT(n)		(K_BCM1480_INT_UART_0 + (n)) -+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) -+#define UNIT_CHANREG(n,reg)	A_DUART_CHANREG((n),(reg)) -+#define UNIT_IMRREG(n)		A_DUART_IMRREG(n) -+#define UNIT_INT(n)		(K_INT_UART_0 + (n)) -+#else -+#error invalid SiByte UART configuation -+#endif -+ -+/* Toggle spewing of debugging output */ -+#undef DEBUG -+ -+#define DEFAULT_CFLAGS          (CS8 | B115200) -+ -+#define TX_INTEN          1 -+#define DUART_INITIALIZED 2 -+ -+#define DUART_MAX_LINE 4 -+char sb1250_duart_present[DUART_MAX_LINE]; -+EXPORT_SYMBOL(sb1250_duart_present); -+ -+/* -+ * In bug 1956, we get glitches that can mess up uart registers.  This -+ * "read-mode-reg after any register access" is an accepted workaround. -+ */ -+#if SIBYTE_1956_WAR -+# define SB1_SER1956_WAR {							\ -+	u32 ignore;										\ -+	ignore = csr_in32(uart_states[line].mode_1);	\ -+	ignore = csr_in32(uart_states[line].mode_2);	\ -+	} -+#else -+# define SB1_SER1956_WAR -+#endif -+ -+/* -+ * Still not sure what the termios structures set up here are for, -+ *  but we have to supply pointers to them to register the tty driver -+ */ -+static struct tty_driver *sb1250_duart_driver; //, sb1250_duart_callout_driver; -+ -+/* -+ * This lock protects both the open flags for all the uart states as -+ * well as the reference count for the module -+ */ -+static DEFINE_SPINLOCK(open_lock); -+ -+typedef struct { -+	unsigned char		outp_buf[SERIAL_XMIT_SIZE]; -+	unsigned int		outp_head; -+	unsigned int		outp_tail; -+	unsigned int		outp_count; -+	spinlock_t		outp_lock; -+	unsigned int		open; -+	unsigned int		line; -+	unsigned int		last_cflags; -+	unsigned long		flags; -+	struct tty_struct	*tty; -+ -+	/* CSR addresses */ -+	unsigned int		*status; -+	unsigned int		*imr; -+	unsigned int		*tx_hold; -+	unsigned int		*rx_hold; -+	unsigned int		*mode_1; -+	unsigned int		*mode_2; -+	unsigned int		*clk_sel; -+	unsigned int		*cmd; -+} uart_state_t; -+ -+static uart_state_t uart_states[DUART_MAX_LINE]; -+ -+/* -+ * Inline functions local to this module -+ */ -+ -+static inline u32 READ_SERCSR(volatile u32 *addr, int line) -+{ -+	u32 val = csr_in32(addr); -+	SB1_SER1956_WAR; -+	return val; -+} -+ -+static inline void WRITE_SERCSR(u32 val, volatile u32 *addr, int line) -+{ -+	csr_out32(val, addr); -+	SB1_SER1956_WAR; -+} -+ -+static void init_duart_port(uart_state_t *port, int line) -+{ -+	if (!(port->flags & DUART_INITIALIZED)) { -+		port->line = line; -+		port->status = IOADDR(UNIT_CHANREG(line, R_DUART_STATUS)); -+		port->imr = IOADDR(UNIT_IMRREG(line)); -+		port->tx_hold = IOADDR(UNIT_CHANREG(line, R_DUART_TX_HOLD)); -+		port->rx_hold = IOADDR(UNIT_CHANREG(line, R_DUART_RX_HOLD)); -+		port->mode_1 = IOADDR(UNIT_CHANREG(line, R_DUART_MODE_REG_1)); -+		port->mode_2 = IOADDR(UNIT_CHANREG(line, R_DUART_MODE_REG_2)); -+		port->clk_sel = IOADDR(UNIT_CHANREG(line, R_DUART_CLK_SEL)); -+		port->cmd = IOADDR(UNIT_CHANREG(line, R_DUART_CMD)); -+		port->last_cflags = DEFAULT_CFLAGS; -+		spin_lock_init(&port->outp_lock); -+		port->flags |= DUART_INITIALIZED; -+	} -+} -+ -+/* -+ * Mask out the passed interrupt lines at the duart level.  This should be -+ * called while holding the associated outp_lock. -+ */ -+static inline void duart_mask_ints(unsigned int line, unsigned int mask) -+{ -+	uart_state_t *port = uart_states + line; -+	u64 tmp = READ_SERCSR(port->imr, line); -+	WRITE_SERCSR(tmp & ~mask, port->imr, line); -+} -+ -+ -+/* Unmask the passed interrupt lines at the duart level */ -+static inline void duart_unmask_ints(unsigned int line, unsigned int mask) -+{ -+	uart_state_t *port = uart_states + line; -+	u64 tmp = READ_SERCSR(port->imr, line); -+	WRITE_SERCSR(tmp | mask, port->imr, line); -+} -+ -+static inline void transmit_char_pio(uart_state_t *us) -+{ -+	struct tty_struct *tty = us->tty; -+	int blocked = 0; -+ -+	if (spin_trylock(&us->outp_lock)) { -+		for (;;) { -+			if (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_RDY)) -+				break; -+			if (us->outp_count <= 0 || tty->stopped || tty->hw_stopped) { -+				break; -+			} else { -+				WRITE_SERCSR(us->outp_buf[us->outp_head], -+					     us->tx_hold, us->line); -+				us->outp_head = (us->outp_head + 1) & (SERIAL_XMIT_SIZE-1); -+				if (--us->outp_count <= 0) -+					break; -+			} -+			udelay(10); -+		} -+		spin_unlock(&us->outp_lock); -+	} else { -+		blocked = 1; -+	} -+ -+	if (!us->outp_count || tty->stopped || -+	    tty->hw_stopped || blocked) { -+		us->flags &= ~TX_INTEN; -+		duart_mask_ints(us->line, M_DUART_IMR_TX); -+	} -+ -+	if (us->open && -+	    (us->outp_count < (SERIAL_XMIT_SIZE/2))) { -+		/* -+		 * We told the discipline at one point that we had no -+		 * space, so it went to sleep.  Wake it up when we hit -+		 * half empty -+		 */ -+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -+		    tty->ldisc.write_wakeup) -+			tty->ldisc.write_wakeup(tty); -+		wake_up_interruptible(&tty->write_wait); -+	} -+} -+ -+/* -+ * Generic interrupt handler for both channels.  dev_id is a pointer -+ * to the proper uart_states structure, so from that we can derive -+ * which port interrupted -+ */ -+ -+static irqreturn_t duart_int(int irq, void *dev_id) -+{ -+	uart_state_t *us = (uart_state_t *)dev_id; -+	struct tty_struct *tty = us->tty; -+	unsigned int status = READ_SERCSR(us->status, us->line); -+ -+	pr_debug("DUART INT\n"); -+ -+	if (status & M_DUART_RX_RDY) { -+		int counter = 2048; -+		unsigned int ch; -+ -+		if (status & M_DUART_OVRUN_ERR) -+			tty_insert_flip_char(tty, 0, TTY_OVERRUN); -+		if (status & M_DUART_PARITY_ERR) { -+			printk("Parity error!\n"); -+		} else if (status & M_DUART_FRM_ERR) { -+			printk("Frame error!\n"); -+		} -+ -+		while (counter > 0) { -+			if (!(READ_SERCSR(us->status, us->line) & M_DUART_RX_RDY)) -+				break; -+			ch = READ_SERCSR(us->rx_hold, us->line); -+			tty_insert_flip_char(tty, ch, 0); -+			udelay(1); -+			counter--; -+		} -+		tty_flip_buffer_push(tty); -+	} -+ -+	if (status & M_DUART_TX_RDY) { -+		transmit_char_pio(us); -+	} -+ -+	return IRQ_HANDLED; -+} -+ -+/* -+ *  Actual driver functions -+ */ -+ -+/* Return the number of characters we can accomodate in a write at this instant */ -+static int duart_write_room(struct tty_struct *tty) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+	int retval; -+ -+	retval = SERIAL_XMIT_SIZE - us->outp_count; -+ -+	pr_debug("duart_write_room called, returning %i\n", retval); -+ -+	return retval; -+} -+ -+/* memcpy the data from src to destination, but take extra care if the -+   data is coming from user space */ -+static inline int copy_buf(char *dest, const char *src, int size, int from_user) -+{ -+	if (from_user) { -+		(void) copy_from_user(dest, src, size); -+	} else { -+		memcpy(dest, src, size); -+	} -+	return size; -+} -+ -+/* -+ * Buffer up to count characters from buf to be written.  If we don't have -+ * other characters buffered, enable the tx interrupt to start sending -+ */ -+static int duart_write(struct tty_struct *tty, const unsigned char *buf, -+		       int count) -+{ -+	uart_state_t *us; -+	int c, t, total = 0; -+	unsigned long flags; -+ -+	if (!tty) return 0; -+ -+	us = tty->driver_data; -+	if (!us) return 0; -+ -+	pr_debug("duart_write called for %i chars by %i (%s)\n", count, -+			current->pid, current->comm); -+ -+	spin_lock_irqsave(&us->outp_lock, flags); -+ -+	for (;;) { -+		c = count; -+ -+		t = SERIAL_XMIT_SIZE - us->outp_tail; -+		if (t < c) c = t; -+ -+		t = SERIAL_XMIT_SIZE - 1 - us->outp_count; -+		if (t < c) c = t; -+ -+		if (c <= 0) break; -+ -+		memcpy(us->outp_buf + us->outp_tail, buf, c); -+ -+		us->outp_count += c; -+		us->outp_tail = (us->outp_tail + c) & (SERIAL_XMIT_SIZE - 1); -+		buf += c; -+		count -= c; -+		total += c; -+	} -+ -+	spin_unlock_irqrestore(&us->outp_lock, flags); -+ -+	if (us->outp_count && !tty->stopped && -+	    !tty->hw_stopped && !(us->flags & TX_INTEN)) { -+		us->flags |= TX_INTEN; -+		duart_unmask_ints(us->line, M_DUART_IMR_TX); -+	} -+ -+	return total; -+} -+ -+ -+/* Buffer one character to be written.  If there's not room for it, just drop -+   it on the floor.  This is used for echo, among other things */ -+static void duart_put_char(struct tty_struct *tty, u_char ch) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+	unsigned long flags; -+ -+	pr_debug("duart_put_char called.  Char is %x (%c)\n", (int)ch, ch); -+ -+	spin_lock_irqsave(&us->outp_lock, flags); -+ -+	if (us->outp_count == SERIAL_XMIT_SIZE) { -+		spin_unlock_irqrestore(&us->outp_lock, flags); -+		return; -+	} -+ -+	us->outp_buf[us->outp_tail] = ch; -+	us->outp_tail = (us->outp_tail + 1) &(SERIAL_XMIT_SIZE-1); -+	us->outp_count++; -+ -+	spin_unlock_irqrestore(&us->outp_lock, flags); -+} -+ -+static void duart_flush_chars(struct tty_struct * tty) -+{ -+	uart_state_t *port; -+ -+	if (!tty) -+		return; -+ -+	port = tty->driver_data; -+ -+	if (!port) -+		return; -+ -+	if (port->outp_count <= 0 || tty->stopped || tty->hw_stopped) { -+		return; -+	} -+ -+	port->flags |= TX_INTEN; -+	duart_unmask_ints(port->line, M_DUART_IMR_TX); -+} -+ -+/* Return the number of characters in the output buffer that have yet to be -+   written */ -+static int duart_chars_in_buffer(struct tty_struct *tty) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+	int retval; -+ -+	retval = us->outp_count; -+ -+	pr_debug("duart_chars_in_buffer returning %i\n", retval); -+ -+	return retval; -+} -+ -+/* Kill everything we haven't yet shoved into the FIFO.  Turn off the -+   transmit interrupt since we've nothing more to transmit */ -+static void duart_flush_buffer(struct tty_struct *tty) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+	unsigned long flags; -+ -+	pr_debug("duart_flush_buffer called\n"); -+	spin_lock_irqsave(&us->outp_lock, flags); -+	us->outp_head = us->outp_tail = us->outp_count = 0; -+	spin_unlock_irqrestore(&us->outp_lock, flags); -+ -+	wake_up_interruptible(&us->tty->write_wait); -+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -+	    tty->ldisc.write_wakeup) -+		tty->ldisc.write_wakeup(tty); -+} -+ -+ -+/* See sb1250 user manual for details on these registers */ -+static inline void duart_set_cflag(unsigned int line, unsigned int cflag) -+{ -+	unsigned int mode_reg1 = 0, mode_reg2 = 0; -+	unsigned int clk_divisor; -+	uart_state_t *port = uart_states + line; -+ -+	switch (cflag & CSIZE) { -+	case CS7: -+		mode_reg1 |= V_DUART_BITS_PER_CHAR_7; -+ -+	default: -+		/* We don't handle CS5 or CS6...is there a way we're supposed to -+		 * flag this?  right now we just force them to CS8 */ -+		mode_reg1 |= 0x0; -+		break; -+	} -+	if (cflag & CSTOPB) { -+	        mode_reg2 |= M_DUART_STOP_BIT_LEN_2; -+	} -+	if (!(cflag & PARENB)) { -+	        mode_reg1 |= V_DUART_PARITY_MODE_NONE; -+	} -+	if (cflag & PARODD) { -+		mode_reg1 |= M_DUART_PARITY_TYPE_ODD; -+	} -+ -+	/* Formula for this is (5000000/baud)-1, but we saturate -+	   at 12 bits, which means we can't actually do anything less -+	   that 1200 baud */ -+	switch (cflag & CBAUD) { -+	case B200: -+	case B300: -+	case B1200:	clk_divisor = 4095;		break; -+	case B1800:	clk_divisor = 2776;		break; -+	case B2400:	clk_divisor = 2082;		break; -+	case B4800:	clk_divisor = 1040;		break; -+	case B9600:	clk_divisor = 519;		break; -+	case B19200:	clk_divisor = 259;		break; -+	case B38400:	clk_divisor = 129;		break; -+	default: -+	case B57600:	clk_divisor = 85;		break; -+	case B115200:	clk_divisor = 42;		break; -+	} -+	WRITE_SERCSR(mode_reg1, port->mode_1, port->line); -+	WRITE_SERCSR(mode_reg2, port->mode_2, port->line); -+	WRITE_SERCSR(clk_divisor, port->clk_sel, port->line); -+	port->last_cflags = cflag; -+} -+ -+ -+/* Handle notification of a termios change.  */ -+static void duart_set_termios(struct tty_struct *tty, struct termios *old) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+ -+	pr_debug("duart_set_termios called by %i (%s)\n", current->pid, -+		current->comm); -+	if (old && tty->termios->c_cflag == old->c_cflag) -+		return; -+	duart_set_cflag(us->line, tty->termios->c_cflag); -+} -+ -+static int get_serial_info(uart_state_t *us, struct serial_struct * retinfo) -+{ -+	struct serial_struct tmp; -+ -+	memset(&tmp, 0, sizeof(tmp)); -+ -+	tmp.type = PORT_SB1250; -+	tmp.line = us->line; -+	tmp.port = UNIT_CHANREG(tmp.line,0); -+	tmp.irq = UNIT_INT(tmp.line); -+	tmp.xmit_fifo_size = 16; /* fixed by hw */ -+	tmp.baud_base = 5000000; -+	tmp.io_type = SERIAL_IO_MEM; -+ -+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) -+		return -EFAULT; -+ -+	return 0; -+} -+ -+static int duart_ioctl(struct tty_struct *tty, struct file * file, -+		       unsigned int cmd, unsigned long arg) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+ -+/*	if (serial_paranoia_check(info, tty->device, "rs_ioctl")) -+	return -ENODEV;*/ -+	switch (cmd) { -+	case TIOCMGET: -+		printk("Ignoring TIOCMGET\n"); -+		break; -+	case TIOCMBIS: -+		printk("Ignoring TIOCMBIS\n"); -+		break; -+	case TIOCMBIC: -+		printk("Ignoring TIOCMBIC\n"); -+		break; -+	case TIOCMSET: -+		printk("Ignoring TIOCMSET\n"); -+		break; -+	case TIOCGSERIAL: -+		return get_serial_info(us,(struct serial_struct *) arg); -+	case TIOCSSERIAL: -+		printk("Ignoring TIOCSSERIAL\n"); -+		break; -+	case TIOCSERCONFIG: -+		printk("Ignoring TIOCSERCONFIG\n"); -+		break; -+	case TIOCSERGETLSR: /* Get line status register */ -+		printk("Ignoring TIOCSERGETLSR\n"); -+		break; -+	case TIOCSERGSTRUCT: -+		printk("Ignoring TIOCSERGSTRUCT\n"); -+		break; -+	case TIOCMIWAIT: -+		printk("Ignoring TIOCMIWAIT\n"); -+		break; -+	case TIOCGICOUNT: -+		printk("Ignoring TIOCGICOUNT\n"); -+		break; -+	case TIOCSERGWILD: -+		printk("Ignoring TIOCSERGWILD\n"); -+		break; -+	case TIOCSERSWILD: -+		printk("Ignoring TIOCSERSWILD\n"); -+		break; -+	default: -+		break; -+	} -+//	printk("Ignoring IOCTL %x from pid %i (%s)\n", cmd, current->pid, current->comm); -+	return -ENOIOCTLCMD; -+} -+ -+/* XXXKW locking? */ -+static void duart_start(struct tty_struct *tty) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+ -+	pr_debug("duart_start called\n"); -+ -+	if (us->outp_count && !(us->flags & TX_INTEN)) { -+		us->flags |= TX_INTEN; -+		duart_unmask_ints(us->line, M_DUART_IMR_TX); -+	} -+} -+ -+/* XXXKW locking? */ -+static void duart_stop(struct tty_struct *tty) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+ -+	pr_debug("duart_stop called\n"); -+ -+	if (us->outp_count && (us->flags & TX_INTEN)) { -+		us->flags &= ~TX_INTEN; -+		duart_mask_ints(us->line, M_DUART_IMR_TX); -+	} -+} -+ -+/* Not sure on the semantics of this; are we supposed to wait until the stuff -+ * already in the hardware FIFO drains, or are we supposed to wait until -+ * we've drained the output buffer, too?  I'm assuming the former, 'cause thats -+ * what the other drivers seem to assume -+ */ -+ -+static void duart_wait_until_sent(struct tty_struct *tty, int timeout) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+	unsigned long orig_jiffies; -+ -+	orig_jiffies = jiffies; -+	pr_debug("duart_wait_until_sent(%d)+\n", timeout); -+	while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) { -+		set_current_state(TASK_INTERRUPTIBLE); -+		schedule_timeout(1); -+		if (signal_pending(current)) -+			break; -+		if (timeout && time_after(jiffies, orig_jiffies + timeout)) -+			break; -+	} -+	pr_debug("duart_wait_until_sent()-\n"); -+} -+ -+/* -+ * duart_hangup() --- called by tty_hangup() when a hangup is signaled. -+ */ -+static void duart_hangup(struct tty_struct *tty) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+ -+	duart_flush_buffer(tty); -+	us->open = 0; -+	us->tty = 0; -+} -+ -+/* -+ * Open a tty line.  Note that this can be called multiple times, so ->open can -+ * be >1.  Only set up the tty struct if this is a "new" open, e.g. ->open was -+ * zero -+ */ -+static int duart_open(struct tty_struct *tty, struct file *filp) -+{ -+	uart_state_t *us; -+	unsigned int line = tty->index; -+	unsigned long flags; -+ -+	if ((line >= tty->driver->num) || !sb1250_duart_present[line]) -+		return -ENODEV; -+ -+	pr_debug("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", -+	       current->pid, current->comm, tty, (void *)&tty->read_wait, -+	       (void *)&tty->write_wait); -+ -+	us = uart_states + line; -+	tty->driver_data = us; -+ -+	spin_lock_irqsave(&open_lock, flags); -+	if (!us->open) { -+		us->tty = tty; -+		us->tty->termios->c_cflag = us->last_cflags; -+	} -+	us->open++; -+	us->flags &= ~TX_INTEN; -+	duart_unmask_ints(line, M_DUART_IMR_RX); -+	spin_unlock_irqrestore(&open_lock, flags); -+ -+	return 0; -+} -+ -+ -+/* -+ * Close a reference count out.  If reference count hits zero, null the -+ * tty, kill the interrupts.  The tty_io driver is responsible for making -+ * sure we've cleared out our internal buffers before calling close() -+ */ -+static void duart_close(struct tty_struct *tty, struct file *filp) -+{ -+	uart_state_t *us = (uart_state_t *) tty->driver_data; -+	unsigned long flags; -+ -+	pr_debug("duart_close called by %i (%s)\n", current->pid, current->comm); -+ -+	if (!us || !us->open) -+		return; -+ -+	spin_lock_irqsave(&open_lock, flags); -+	if (tty_hung_up_p(filp)) { -+		spin_unlock_irqrestore(&open_lock, flags); -+		return; -+	} -+ -+	if (--us->open < 0) { -+		us->open = 0; -+		printk(KERN_ERR "duart: bad open count: %d\n", us->open); -+	} -+	if (us->open) { -+		spin_unlock_irqrestore(&open_lock, flags); -+		return; -+	} -+ -+	spin_unlock_irqrestore(&open_lock, flags); -+ -+	tty->closing = 1; -+ -+	/* Stop accepting input */ -+	duart_mask_ints(us->line, M_DUART_IMR_RX); -+	/* Wait for FIFO to drain */ -+	while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) -+		; -+ -+	if (tty->driver->flush_buffer) -+		tty->driver->flush_buffer(tty); -+	if (tty->ldisc.flush_buffer) -+		tty->ldisc.flush_buffer(tty); -+	tty->closing = 0; -+} -+ -+ -+static struct tty_operations duart_ops = { -+        .open   = duart_open, -+        .close = duart_close, -+        .write = duart_write, -+        .put_char = duart_put_char, -+        .flush_chars = duart_flush_chars, -+        .write_room = duart_write_room, -+        .chars_in_buffer = duart_chars_in_buffer, -+        .flush_buffer = duart_flush_buffer, -+        .ioctl = duart_ioctl, -+//        .throttle = duart_throttle, -+//        .unthrottle = duart_unthrottle, -+        .set_termios = duart_set_termios, -+        .stop = duart_stop, -+        .start = duart_start, -+        .hangup = duart_hangup, -+	.wait_until_sent = duart_wait_until_sent, -+}; -+ -+/* Initialize the sb1250_duart_present array based on SOC type.  */ -+static void __init sb1250_duart_init_present_lines(void) -+{ -+	int i, max_lines; -+ -+	/* Set the number of available units based on the SOC type.  */ -+	switch (soc_type) { -+	case K_SYS_SOC_TYPE_BCM1x55: -+	case K_SYS_SOC_TYPE_BCM1x80: -+		max_lines = 4; -+		break; -+	default: -+		/* Assume at least two serial ports at the normal address.  */ -+		max_lines = 2; -+		break; -+	} -+	if (max_lines > DUART_MAX_LINE) -+		max_lines = DUART_MAX_LINE; -+ -+	for (i = 0; i < max_lines; i++) -+		sb1250_duart_present[i] = 1; -+} -+ -+/* Set up the driver and register it, register the UART interrupts.  This -+   is called from tty_init, or as a part of the module init */ -+static int __init sb1250_duart_init(void) -+{ -+	int i; -+ -+	sb1250_duart_init_present_lines(); -+ -+	sb1250_duart_driver = alloc_tty_driver(DUART_MAX_LINE); -+	if (!sb1250_duart_driver) -+		return -ENOMEM; -+ -+	sb1250_duart_driver->owner = THIS_MODULE; -+	sb1250_duart_driver->name = "duart"; -+	sb1250_duart_driver->major = TTY_MAJOR; -+	sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE; -+	sb1250_duart_driver->type            = TTY_DRIVER_TYPE_SERIAL; -+	sb1250_duart_driver->subtype         = SERIAL_TYPE_NORMAL; -+	sb1250_duart_driver->init_termios    = tty_std_termios; -+	sb1250_duart_driver->flags           = TTY_DRIVER_REAL_RAW; -+	tty_set_operations(sb1250_duart_driver, &duart_ops); -+ -+	for (i = 0; i < DUART_MAX_LINE; i++) { -+		uart_state_t *port = uart_states + i; -+ -+		if (!sb1250_duart_present[i]) -+			continue; -+ -+		init_duart_port(port, i); -+		duart_mask_ints(i, M_DUART_IMR_ALL); -+		if (request_irq(UNIT_INT(i), duart_int, 0, "uart", port)) { -+			panic("Couldn't get uart0 interrupt line"); -+		} -+		/* -+		 * this generic write to a register does not implement the 1956 -+		 * WAR and sometimes output gets corrupted afterwards, -+		 * especially if the port was in use as a console. -+		 */ -+		__raw_writel(M_DUART_RX_EN|M_DUART_TX_EN, port->cmd); -+ -+		/* -+		 * we should really check to see if it's registered as a console -+		 * before trashing those settings -+		 */ -+		duart_set_cflag(i, port->last_cflags); -+	} -+ -+	/* Interrupts are now active, our ISR can be called. */ -+ -+	if (tty_register_driver(sb1250_duart_driver)) { -+		printk(KERN_ERR "Couldn't register sb1250 duart serial driver\n"); -+		put_tty_driver(sb1250_duart_driver); -+		return 1; -+	} -+	return 0; -+} -+ -+/* Unload the driver.  Unregister stuff, get ready to go away */ -+static void __exit sb1250_duart_fini(void) -+{ -+	unsigned long flags; -+	int i; -+ -+	local_irq_save(flags); -+	tty_unregister_driver(sb1250_duart_driver); -+	put_tty_driver(sb1250_duart_driver); -+ -+	for (i = 0; i < DUART_MAX_LINE; i++) { -+		if (!sb1250_duart_present[i]) -+			continue; -+		free_irq(UNIT_INT(i), &uart_states[i]); -+		disable_irq(UNIT_INT(i)); -+	} -+	local_irq_restore(flags); -+} -+ -+module_init(sb1250_duart_init); -+module_exit(sb1250_duart_fini); -+MODULE_DESCRIPTION("SB1250 Duart serial driver"); -+MODULE_AUTHOR("Broadcom Corp."); -+ -+#ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE -+ -+/* -+ * Serial console stuff.  Very basic, polling driver for doing serial -+ * console output.  The console_sem is held by the caller, so we -+ * shouldn't be interrupted for more console activity. -+ * XXXKW What about getting interrupted by uart driver activity? -+ */ -+ -+void serial_outc(unsigned char c, int line) -+{ -+	uart_state_t *port = uart_states + line; -+	while (!(READ_SERCSR(port->status, line) & M_DUART_TX_RDY)) ; -+	WRITE_SERCSR(c, port->tx_hold, line); -+	while (!(READ_SERCSR(port->status, port->line) & M_DUART_TX_EMT)) ; -+} -+ -+static void ser_console_write(struct console *cons, const char *s, -+	unsigned int count) -+{ -+	int line = cons->index; -+	uart_state_t *port = uart_states + line; -+	u32 imr; -+ -+	imr = READ_SERCSR(port->imr, line); -+	WRITE_SERCSR(0, port->imr, line); -+	while (count--) { -+		if (*s == '\n') -+			serial_outc('\r', line); -+		serial_outc(*s++, line); -+	} -+	WRITE_SERCSR(imr, port->imr, line); -+} -+ -+static struct tty_driver *ser_console_device(struct console *c, int *index) -+{ -+	*index = c->index; -+	return sb1250_duart_driver; -+} -+ -+static int ser_console_setup(struct console *cons, char *str) -+{ -+	int i; -+ -+	sb1250_duart_init_present_lines(); -+ -+	for (i = 0; i < DUART_MAX_LINE; i++) { -+		uart_state_t *port = uart_states + i; -+		u32 cflags = DEFAULT_CFLAGS; -+ -+		if (!sb1250_duart_present[i]) -+			continue; -+ -+		init_duart_port(port, i); -+		if (str) { -+			int speed; -+			char par = 'n'; -+			int cbits = 8; -+ -+			cflags = 0; -+ -+			/* -+			 * format is in Documentation/serial_console.txt -+			 */ -+			sscanf(str, "%d%c%d", &speed, &par, &cbits); -+ -+			switch (speed) { -+			case 200: -+			case 300: -+			case 1200: -+				cflags |= B1200; -+				break; -+			case 1800: -+				cflags |= B1800; -+				break; -+			case 2400: -+				cflags |= B2400; -+				break; -+			case 4800: -+				cflags |= B4800; -+				break; -+			default: -+			case 9600: -+				cflags |= B9600; -+				break; -+			case 19200: -+				cflags |= B19200; -+				break; -+			case 38400: -+				cflags |= B38400; -+				break; -+			case 57600: -+				cflags |= B57600; -+				break; -+			case 115200: -+				cflags |= B115200; -+				break; -+			} -+			switch (par) { -+			case 'o': -+				cflags |= PARODD; -+			case 'e': -+				cflags |= PARENB; -+			} -+			switch (cbits) { -+			default:	// we only do 7 or 8 -+			case 8: -+				cflags |= CS8; -+				break; -+			case 7: -+				cflags |= CS7; -+				break; -+			} -+		} -+		duart_set_cflag(i, cflags); -+		WRITE_SERCSR(M_DUART_RX_EN | M_DUART_TX_EN, port->cmd, i); -+	} -+ -+	return 0; -+} -+ -+static struct console sb1250_ser_cons = { -+	.name		= "duart", -+	.write		= ser_console_write, -+	.device		= ser_console_device, -+	.setup		= ser_console_setup, -+	.flags		= CON_PRINTBUFFER, -+	.index		= -1, -+}; -+ -+static int __init sb1250_serial_console_init(void) -+{ -+	//add_preferred_console("duart", 0, "57600n8"); -+	register_console(&sb1250_ser_cons); -+	return 0; -+} -+ -+console_initcall(sb1250_serial_console_init); -+ -+#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */ -diff -Nur linux-2.6.21.1/include/linux/serial.h linux-2.6.21.1-owrt/include/linux/serial.h ---- linux-2.6.21.1/include/linux/serial.h	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1-owrt/include/linux/serial.h	2007-05-24 22:10:29.000000000 +0200 -@@ -76,7 +76,8 @@ - #define PORT_16654	11 - #define PORT_16850	12 - #define PORT_RSA	13	/* RSA-DV II/S card */ --#define PORT_MAX	13 -+#define PORT_SB1250	14 -+#define PORT_MAX	14 -  - #define SERIAL_IO_PORT	0 - #define SERIAL_IO_HUB6	1 | 
