diff options
Diffstat (limited to 'target/linux/etrax/patches-2.6.29/600-fix_serial_cris.patch')
-rw-r--r-- | target/linux/etrax/patches-2.6.29/600-fix_serial_cris.patch | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/target/linux/etrax/patches-2.6.29/600-fix_serial_cris.patch b/target/linux/etrax/patches-2.6.29/600-fix_serial_cris.patch new file mode 100644 index 0000000000..7ac24a474b --- /dev/null +++ b/target/linux/etrax/patches-2.6.29/600-fix_serial_cris.patch @@ -0,0 +1,265 @@ +Index: linux-2.6.28.9/drivers/serial/crisv10.c +=================================================================== +--- linux-2.6.28.9.orig/drivers/serial/crisv10.c 2009-04-10 12:58:18.000000000 +0200 ++++ linux-2.6.28.9/drivers/serial/crisv10.c 2009-04-10 12:58:22.000000000 +0200 +@@ -28,12 +28,15 @@ + #include <linux/mutex.h> + #include <linux/bitops.h> + #include <linux/device.h> ++#include <linux/seq_file.h> ++#include <linux/delay.h> ++#include <linux/module.h> ++#include <linux/uaccess.h> ++#include <linux/io.h> + +-#include <asm/io.h> + #include <asm/irq.h> + #include <asm/dma.h> + #include <asm/system.h> +-#include <linux/delay.h> + + #include <arch/svinto.h> + +@@ -457,7 +460,6 @@ + + #define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) + +-static struct ktermios *serial_termios[NR_PORTS]; + #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER + static struct fast_timer fast_timers[NR_PORTS]; + #endif +@@ -4221,151 +4223,132 @@ + return 0; + } + ++#ifdef CONFIG_PROC_FS + /* + * /proc fs routines.... + */ + +-static int line_info(char *buf, struct e100_serial *info) ++static void seq_line_info(struct seq_file *m, struct e100_serial *info) + { +- char stat_buf[30]; +- int ret; + unsigned long tmp; + +- ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d", +- info->line, (unsigned long)info->ioport, info->irq); ++ seq_printf(m, "%d: uart:E100 port:%lX irq:%d", ++ info->line, (unsigned long)info->ioport, info->irq); + + if (!info->ioport || (info->type == PORT_UNKNOWN)) { +- ret += sprintf(buf+ret, "\n"); +- return ret; ++ seq_printf(m, "\n"); ++ return; + } + +- stat_buf[0] = 0; +- stat_buf[1] = 0; +- if (!E100_RTS_GET(info)) +- strcat(stat_buf, "|RTS"); +- if (!E100_CTS_GET(info)) +- strcat(stat_buf, "|CTS"); +- if (!E100_DTR_GET(info)) +- strcat(stat_buf, "|DTR"); +- if (!E100_DSR_GET(info)) +- strcat(stat_buf, "|DSR"); +- if (!E100_CD_GET(info)) +- strcat(stat_buf, "|CD"); +- if (!E100_RI_GET(info)) +- strcat(stat_buf, "|RI"); +- +- ret += sprintf(buf+ret, " baud:%d", info->baud); +- +- ret += sprintf(buf+ret, " tx:%lu rx:%lu", ++ seq_printf(m, " baud:%d", info->baud); ++ seq_printf(m, " tx:%lu rx:%lu", + (unsigned long)info->icount.tx, + (unsigned long)info->icount.rx); + tmp = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +- if (tmp) { +- ret += sprintf(buf+ret, " tx_pend:%lu/%lu", +- (unsigned long)tmp, +- (unsigned long)SERIAL_XMIT_SIZE); +- } +- +- ret += sprintf(buf+ret, " rx_pend:%lu/%lu", +- (unsigned long)info->recv_cnt, +- (unsigned long)info->max_recv_cnt); ++ if (tmp) ++ seq_printf(m, " tx_pend:%lu/%lu", ++ (unsigned long)tmp, ++ (unsigned long)SERIAL_XMIT_SIZE); ++ ++ seq_printf(m, " rx_pend:%lu/%lu", ++ (unsigned long)info->recv_cnt, ++ (unsigned long)info->max_recv_cnt); + + #if 1 + if (info->port.tty) { +- + if (info->port.tty->stopped) +- ret += sprintf(buf+ret, " stopped:%i", +- (int)info->port.tty->stopped); ++ seq_printf(m, " stopped:%i", ++ (int)info->port.tty->stopped); + if (info->port.tty->hw_stopped) +- ret += sprintf(buf+ret, " hw_stopped:%i", +- (int)info->port.tty->hw_stopped); ++ seq_printf(m, " hw_stopped:%i", ++ (int)info->port.tty->hw_stopped); + } + + { + unsigned char rstat = info->ioport[REG_STATUS]; +- if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) +- ret += sprintf(buf+ret, " xoff_detect:1"); ++ if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect)) ++ seq_printf(m, " xoff_detect:1"); + } + + #endif + +- +- +- + if (info->icount.frame) +- ret += sprintf(buf+ret, " fe:%lu", +- (unsigned long)info->icount.frame); ++ seq_printf(m, " fe:%lu", (unsigned long)info->icount.frame); + + if (info->icount.parity) +- ret += sprintf(buf+ret, " pe:%lu", +- (unsigned long)info->icount.parity); ++ seq_printf(m, " pe:%lu", (unsigned long)info->icount.parity); + + if (info->icount.brk) +- ret += sprintf(buf+ret, " brk:%lu", +- (unsigned long)info->icount.brk); ++ seq_printf(m, " brk:%lu", (unsigned long)info->icount.brk); + + if (info->icount.overrun) +- ret += sprintf(buf+ret, " oe:%lu", +- (unsigned long)info->icount.overrun); ++ seq_printf(m, " oe:%lu", (unsigned long)info->icount.overrun); + + /* + * Last thing is the RS-232 status lines + */ +- ret += sprintf(buf+ret, " %s\n", stat_buf+1); +- return ret; ++ if (!E100_RTS_GET(info)) ++ seq_puts(m, "|RTS"); ++ if (!E100_CTS_GET(info)) ++ seq_puts(m, "|CTS"); ++ if (!E100_DTR_GET(info)) ++ seq_puts(m, "|DTR"); ++ if (!E100_DSR_GET(info)) ++ seq_puts(m, "|DSR"); ++ if (!E100_CD_GET(info)) ++ seq_puts(m, "|CD"); ++ if (!E100_RI_GET(info)) ++ seq_puts(m, "|RI"); ++ seq_puts(m, "\n"); + } + +-int rs_read_proc(char *page, char **start, off_t off, int count, +- int *eof, void *data) ++ ++static int crisv10_proc_show(struct seq_file *m, void *v) + { +- int i, len = 0, l; +- off_t begin = 0; ++ int i; ++ ++ seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); + +- len += sprintf(page, "serinfo:1.0 driver:%s\n", +- serial_version); +- for (i = 0; i < NR_PORTS && len < 4000; i++) { ++ for (i = 0; i < NR_PORTS; i++) { + if (!rs_table[i].enabled) + continue; +- l = line_info(page + len, &rs_table[i]); +- len += l; +- if (len+begin > off+count) +- goto done; +- if (len+begin < off) { +- begin += len; +- len = 0; +- } ++ seq_line_info(m, &rs_table[i]); + } + #ifdef DEBUG_LOG_INCLUDED + for (i = 0; i < debug_log_pos; i++) { +- len += sprintf(page + len, "%-4i %lu.%lu ", i, debug_log[i].time, timer_data_to_ns(debug_log[i].timer_data)); +- len += sprintf(page + len, debug_log[i].string, debug_log[i].value); +- if (len+begin > off+count) +- goto done; +- if (len+begin < off) { +- begin += len; +- len = 0; +- } ++ seq_printf(m, "%-4i %lu.%lu ", ++ i, debug_log[i].time, ++ timer_data_to_ns(debug_log[i].timer_data)); ++ seq_printf(m, debug_log[i].string, debug_log[i].value); + } +- len += sprintf(page + len, "debug_log %i/%i %li bytes\n", +- i, DEBUG_LOG_SIZE, begin+len); ++ seq_printf(m, "debug_log %i/%i\n", i, DEBUG_LOG_SIZE); + debug_log_pos = 0; + #endif ++ return 0; ++} + +- *eof = 1; +-done: +- if (off >= len+begin) +- return 0; +- *start = page + (off-begin); +- return ((count < begin+len-off) ? count : begin+len-off); ++static int crisv10_proc_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, crisv10_proc_show, NULL); + } + ++static const struct file_operations crisv10_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = crisv10_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++#endif ++ ++ + /* Finally, routines used to initialize the serial driver. */ + +-static void +-show_serial_version(void) ++static void show_serial_version(void) + { + printk(KERN_INFO +- "ETRAX 100LX serial-driver %s, (c) 2000-2004 Axis Communications AB\r\n", ++ "ETRAX 100LX serial-driver %s, " ++ "(c) 2000-2004 Axis Communications AB\r\n", + &serial_version[11]); /* "$Revision: x.yy" */ + } + +@@ -4389,9 +4372,11 @@ + .break_ctl = rs_break, + .send_xchar = rs_send_xchar, + .wait_until_sent = rs_wait_until_sent, +- .read_proc = rs_read_proc, + .tiocmget = rs_tiocmget, +- .tiocmset = rs_tiocmset ++ .tiocmset = rs_tiocmset, ++#ifdef CONFIG_PROC_FS ++ .proc_fops = &crisv10_proc_fops, ++#endif + }; + + static struct class *rs_class; |