Remove arm/mips patches that are no longer needed

svn path=/dists/trunk/linux-2.6/; revision=9377
This commit is contained in:
Martin Michlmayr 2007-08-24 13:01:48 +00:00
parent 232fca370b
commit 0d11e52c05
6 changed files with 0 additions and 1251 deletions

View File

@ -1,15 +0,0 @@
# fixed in a beter way in 2.6.23
Autodetect the RTC chip.
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -16,7 +16,7 @@ #include <linux/bcd.h>
#define DRV_VERSION "0.3"
/* Addresses to scan */
-static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x32, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD;

View File

@ -1,18 +0,0 @@
## DP: Tulip - fixes compile on MIPS64.
## DP: Path author: Peter Horton <pdh@colonel-panic.org>
## DP: Not sure whether this is needed or not, but we've had it for
## DP: quite a while. I'll try to find out -- tbm
--- a/drivers/net/tulip/tulip_core.c 2007-05-21 11:12:45.000000000 +0000
+++ b/drivers/net/tulip/tulip_core.c 2007-05-21 11:13:10.000000000 +0000
@@ -1490,8 +1490,8 @@
(PCI_SLOT(pdev->devfn) == 12))) {
/* Cobalt MAC address in first EEPROM locations. */
sa_offset = 0;
- /* Ensure our media table fixup get's applied */
- memcpy(ee_data + 16, ee_data, 8);
+ /* No media table either */
+ tp->flags &= ~HAS_MEDIA_TABLE;
}
#endif
#ifdef CONFIG_GSC

View File

@ -1,24 +0,0 @@
# Upstream status: in linux-mips tree; someone needs to figure out how to
# integrate this into the Linux tree...
# will be in 2.6.23
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -865,6 +865,7 @@ ip22zilog_set_termios(struct uart_port *
up->cflag = termios->c_cflag;
ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
+ uart_update_timeout(port, termios->c_cflag, baud);
spin_unlock_irqrestore(&up->port.lock, flags);
}
@@ -1026,6 +1027,8 @@ ip22serial_console_termios(struct consol
}
con->cflag = cflag | CS8; /* 8N1 */
+
+ uart_update_timeout(&ip22zilog_port_table[con->index].port, cflag, baud);
}
static int __init ip22zilog_console_setup(struct console *con, char *options)

View File

@ -1,231 +0,0 @@
# Qemu kernel config for mips/mipsel, from linux-mips.org 2.6.18-stable,
# some initialization bits should eventually happen in qemu BIOS.
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile
index 078cd30..493259c 100644
--- a/arch/mips/qemu/Makefile
+++ b/arch/mips/qemu/Makefile
@@ -4,4 +4,5 @@ #
obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
+obj-$(CONFIG_VT) += q-vga.o
obj-$(CONFIG_SMP) += q-smp.o
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
index 8413943..37c2f73 100644
--- a/arch/mips/qemu/q-setup.c
+++ b/arch/mips/qemu/q-setup.c
@@ -2,6 +2,7 @@ #include <linux/init.h>
#include <asm/io.h>
#include <asm/time.h>
+extern void qvga_init(void);
extern void qemu_reboot_setup(void);
#define QEMU_PORT_BASE 0xb4000000
@@ -23,5 +24,9 @@ void __init plat_timer_setup(struct irqa
void __init plat_mem_setup(void)
{
set_io_port_base(QEMU_PORT_BASE);
+#ifdef CONFIG_VT
+ qvga_init();
+#endif
+
qemu_reboot_setup();
}
diff --git a/arch/mips/qemu/q-vga.c b/arch/mips/qemu/q-vga.c
new file mode 100644
index 0000000..e26109a
--- /dev/null
+++ b/arch/mips/qemu/q-vga.c
@@ -0,0 +1,189 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This will eventually go into the qemu firmware.
+ */
+#include <linux/init.h>
+#include <linux/screen_info.h>
+#include <linux/tty.h>
+#include <asm/io.h>
+#include <video/vga.h>
+
+/*
+ * This will eventually be done by the firmware; right now Linux assumes to
+ * run on the uninitialized hardware.
+ */
+#undef LOAD_VGA_FONT
+
+static unsigned char sr[8] __initdata = { /* Sequencer */
+ 0x03, 0x00, 0x03, 0x04, 0x02, 0x00, 0x00, 0x00
+};
+
+static unsigned char gr[16] __initdata= { /* Graphics Controller */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char ar[21] __initdata= { /* Attribute Controller */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x0c, 0x01, 0x07, 0x13, 0x00
+};
+
+static unsigned char cr[32] __initdata= { /* CRT Controller */
+ 0x91, 0x4f, 0x4f, 0x95, 0x57, 0x4f, 0xc0, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x02, 0x30, 0x09, 0xb0,
+ 0x90, 0x83, 0x8f, 0x28, 0x1f, 0x8f, 0xc1, 0xa3,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static struct rgb {
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+} palette[16] __initdata= {
+ [ 0] = {0x00, 0x00, 0x00},
+ [ 1] = {0x00, 0x00, 0x2a},
+ [ 2] = {0x00, 0x2a, 0x00},
+ [ 3] = {0x00, 0x2a, 0x2a},
+ [ 4] = {0x2a, 0x00, 0x00},
+ [ 5] = {0x2a, 0x00, 0x2a},
+ [ 6] = {0x2a, 0x15, 0x00},
+ [ 7] = {0x2a, 0x2a, 0x2a},
+ [ 8] = {0x15, 0x15, 0x15},
+ [ 9] = {0x15, 0x15, 0x3f},
+ [10] = {0x15, 0x3f, 0x15},
+ [11] = {0x15, 0x3f, 0x3f},
+ [12] = {0x3f, 0x15, 0x15},
+ [13] = {0x3f, 0x15, 0x3f},
+ [14] = {0x3f, 0x3f, 0x15},
+ [15] = {0x3f, 0x3f, 0x3f}
+
+};
+
+void __init qvga_init_ibm(void)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) { /* Sequencer registers */
+ outb(i, 0x3c4);
+ outb(sr[i], 0x3c5);
+ }
+
+ for (i = 0; i < 16; i++) { /* Graphics Controller registers */
+ outb(i, 0x3ce);
+ outb(gr[i], 0x3cf);
+ }
+
+ for (i = 0; i < 21; i++) { /* Attribute Controller registers */
+ outb(i, 0x3c0);
+ outb(ar[i], 0x3c1);
+ }
+ outb(0x20, 0x3c0); /* enable bit in *index* register */
+
+ for (i = 0; i < 32; i++) { /* CRT Controller registers */
+ outb(i, 0x3d4);
+ outb(cr[i], 0x3d5);
+ }
+
+ for (i = 0; i < 16; i++) { /* palette */
+ outb(i, 0x3c8);
+ outb(palette[i].r, 0x3c9);
+ outb(palette[i].g, 0x3c9);
+ outb(palette[i].b, 0x3c9);
+ }
+
+#if 1
+ for (i = 0; i < 0x20000; i += 2)
+ *(volatile unsigned short *) (0xb00a0000 + i) = 0xaaaa;
+#endif
+}
+
+#ifdef LOAD_VGA_FONT
+#include "/home/ralf/src/qemu/qemu-mips/vgafont.h"
+
+static void __init
+qvga_load_font(unsigned char *def, unsigned int c)
+{
+ volatile void *w = (volatile void *) 0xb00a0000;
+
+ vga_wseq(NULL, 0, 1);
+ vga_wseq(NULL, 2, 4);
+ vga_wseq(NULL, 4, 7);
+ vga_wseq(NULL, 0, 3);
+ vga_wgfx(NULL, 4, 2);
+ vga_wgfx(NULL, 5, 0);
+ vga_wgfx(NULL, 6, 0);
+
+ memcpy(w, def, c);
+
+ vga_wseq(NULL, 0, 1);
+ vga_wseq(NULL, 2, 3);
+ vga_wseq(NULL, 4, 3);
+ vga_wseq(NULL, 0, 3);
+ vga_wgfx(NULL, 4, 0);
+ vga_wgfx(NULL, 5, 0x10);
+ vga_wgfx(NULL, 6, 0xe);
+}
+#endif
+
+void __init qvga_init(void)
+{
+ struct screen_info *si = &screen_info;
+ unsigned int h;
+ int i;
+
+#if LOAD_VGA_FONT
+ qvga_load_font(vgafont16, 4096);
+#endif
+
+ vga_wgfx(NULL, 5, 0x10); /* Set odd/even mode */
+ vga_wgfx(NULL, 6, 0x0c); /* map to offset 0xb8000, text mode */
+ vga_wseq(NULL, 2, 3); /* Planes 0 & 1 */
+ vga_wseq(NULL, 3, 4); /* Font offset */
+ outb(1, VGA_MIS_W); /* set msr to MSR_COLOR_EMULATION */
+ vga_wcrt(NULL, 1, 79); /* 80 columns */
+ vga_wcrt(NULL, 9, 15); /* 16 pixels per character */
+ vga_wcrt(NULL, 0x0c, 0); /* start address high 8 bit */
+ vga_wcrt(NULL, 0x0d, 0); /* start address low 8 bit */
+ vga_wcrt(NULL, 0x13, 0x28); /* line offset */
+ vga_wcrt(NULL, 0x07, 0x1f); /* line compare bit 8 */
+ vga_wcrt(NULL, 0x09, 0x4f); /* line compare bit 9 */
+ vga_wcrt(NULL, 0x18, 0xff); /* line compare low 8 bit */
+
+ h = (25 * 16);
+ vga_wcrt(NULL, 0x12, h);
+
+ outb(7, 0x3d4);
+ outb((inb(0x3d5) & ~0x42) | ((h >> 7) & 2) | ((h >> 3) & 0x40), 0x3d5);
+
+ for (i = 0; i < 21; i++) /* Attribute Controller */
+ vga_wattr(NULL, i, ar[i]);
+ outb(0x20, 0x3c0); /* Set bit 5 in Attribute Controller */
+ /* index ... VGA is so stupid I want */
+ /* to cry all day ... */
+ outb(0, VGA_PEL_IW);
+ for (i = 0; i < 16; i++) { /* palette */
+ outb(palette[i].r, VGA_PEL_D);
+ outb(palette[i].g, VGA_PEL_D);
+ outb(palette[i].b, VGA_PEL_D);
+ }
+
+ si->orig_x = 0; /* Cursor x position */
+ si->orig_y = 0; /* Cursor y position */
+ si->orig_video_cols = 80; /* Columns */
+ si->orig_video_lines = 25; /* Lines */
+ si->orig_video_isVGA = VIDEO_TYPE_VGAC; /* Card type */
+ si->orig_video_points = 16;
+
+#if 0
+ for (i = 0; i < 80; i += 2)
+ //*(volatile unsigned short *) (0xb00b8000 + i) = 0x0100 | 'A';
+ scr_writew(0x0100 | 'A', (volatile unsigned short *) (0xb00b8000 + i));
+ while (1);
+#endif
+}

View File

@ -1,958 +0,0 @@
DUART support for Sibyte SB1
Status: in linux-mips git; still needs to be merged into mainline
--- a/include/linux/serial.h~ 2006-03-13 19:32:04.000000000 +0000
+++ b/include/linux/serial.h 2006-03-13 19:32:27.000000000 +0000
@@ -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
--- a/drivers/char/Kconfig~ 2007-04-25 15:13:07.000000000 +0000
+++ b/drivers/char/Kconfig 2007-04-25 15:13:10.000000000 +0000
@@ -419,6 +419,14 @@
Documentation on the Zilog 85C350 serial communications controller
is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf>
+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 A2232
tristate "Commodore A2232 serial support (EXPERIMENTAL)"
depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 503dd90..2db5532 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_ISTALLION) += istallion.o
obj-$(CONFIG_DIGIEPCA) += epca.o
obj-$(CONFIG_SPECIALIX) += specialix.o
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
+obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o
obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o
obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
--- /dev/null 2007-01-01 17:07:00.000000000 +0000
+++ b/drivers/char/sb1250_duart.c 2007-04-26 11:42:00.000000000 +0000
@@ -0,0 +1,909 @@
+/*
+ * 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);
+
+/*
+ * 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 */
+ volatile u32 *status;
+ volatile u32 *imr;
+ volatile u32 *tx_hold;
+ volatile u32 *rx_hold;
+ volatile u32 *mode_1;
+ volatile u32 *mode_2;
+ volatile u32 *clk_sel;
+ volatile u32 *cmd;
+} uart_state_t;
+
+static uart_state_t uart_states[DUART_MAX_LINE];
+
+/*
+ * Inline functions local to this module
+ */
+
+/*
+ * In bug 1956, we get glitches that can mess up uart registers. This
+ * "write-mode-1 after any register access" is the accepted
+ * workaround.
+ */
+#if SIBYTE_1956_WAR
+static unsigned int last_mode1[DUART_MAX_LINE];
+#endif
+
+static inline u32 READ_SERCSR(volatile u32 *addr, int line)
+{
+ u32 val = csr_in32(addr);
+#if SIBYTE_1956_WAR
+ csr_out32(last_mode1[line], uart_states[line].mode_1);
+#endif
+ return val;
+}
+
+static inline void WRITE_SERCSR(u32 val, volatile u32 *addr, int line)
+{
+ csr_out32(val, addr);
+#if SIBYTE_1956_WAR
+ csr_out32(last_mode1[line], uart_states[line].mode_1);
+#endif
+}
+
+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->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, struct pt_regs *regs)
+{
+ 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;
+ default:
+ case B9600: clk_divisor = 519; break;
+ case B19200: clk_divisor = 259; break;
+ case B38400: clk_divisor = 129; break;
+ 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, tty->read_wait,
+ 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 = "ttyS";
+ 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);
+ spin_lock_init(&port->outp_lock);
+ 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");
+ }
+ __raw_writeq(M_DUART_RX_EN|M_DUART_TX_EN,
+ IOADDR(UNIT_CHANREG(i, R_DUART_CMD)));
+ duart_set_cflag(i, DEFAULT_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;
+
+ if (!sb1250_duart_present[i])
+ continue;
+
+ init_duart_port(port, i);
+#if SIBYTE_1956_WAR
+ last_mode1[i] = V_DUART_PARITY_MODE_NONE|V_DUART_BITS_PER_CHAR_8;
+#endif
+ WRITE_SERCSR(V_DUART_PARITY_MODE_NONE|V_DUART_BITS_PER_CHAR_8,
+ port->mode_1, i);
+ WRITE_SERCSR(M_DUART_STOP_BIT_LEN_1,
+ port->mode_2, i);
+ WRITE_SERCSR(V_DUART_BAUD_RATE(115200),
+ port->clk_sel, i);
+ WRITE_SERCSR(M_DUART_RX_EN|M_DUART_TX_EN,
+ port->cmd, i);
+ }
+ return 0;
+}
+
+static struct console sb1250_ser_cons = {
+ .name = "ttyS",
+ .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)
+{
+ register_console(&sb1250_ser_cons);
+ return 0;
+}
+
+console_initcall(sb1250_serial_console_init);
+
+#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */

View File

@ -13,13 +13,9 @@
+ bugfix/powerpc/prep-utah-ide-interrupt.patch
+ bugfix/powerpc/serial.patch
+ bugfix/mips/ide-scan.patch
#+ bugfix/mips/ip22-zilog-console.patch
+ bugfix/mips/sgi-ioc3.patch
+ bugfix/mips/64bit-tulip.patch
+ bugfix/mips/tulip_dc21143.patch
+ bugfix/mips/cobalt-ide-resources.patch
#+ features/mips/qemu-vga.patch
#+ features/mips/sb1-duart.patch
#+ features/arm/ixp4xx-npe-driver-0.3.1.patch
#+ features/arm/ixp4xx-net-driver-improve-mac-handling.patch
+ features/arm/nslu2-i2c-gpio-driver-support.patch
@ -30,7 +26,6 @@
+ features/arm/nas100d-setup-mac.patch
#+ bugfix/drivers-bus_to_virt.patch
+ bugfix/sparc/drivers_net-broken.patch
#+ bugfix/arm/rtc-rs5c372-n2100.patch
+ bugfix/forcedeth-napi-broken.patch
#+ bugfix/powerpc/drivers_macintosh-broken.patch
+ bugfix/ia64/hardcode-arch-script-output.patch