diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 14:08:47 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 14:08:47 -0800 |
commit | c6bd5bcc4983f1a2d2f87a3769bf309482ee8c04 (patch) | |
tree | 2ff9c4496dc2258d601a1bcd82040470704dae3b /drivers/staging | |
parent | 8966961b31c251b854169e9886394c2a20f2cea7 (diff) | |
parent | b0ab02361167faa82198b783a8d555eb6f58901c (diff) |
Merge tag 'tty-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY/Serial merge from Greg Kroah-Hartman:
"Here's the big tty/serial tree set of changes for 3.8-rc1.
Contained in here is a bunch more reworks of the tty port layer from
Jiri and bugfixes from Alan, along with a number of other tty and
serial driver updates by the various driver authors.
Also, Jiri has been coerced^Wconvinced to be the co-maintainer of the
TTY layer, which is much appreciated by me.
All of these have been in the linux-next tree for a while.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Fixed up some trivial conflicts in the staging tree, due to the fwserial
driver having come in both ways (but fixed up a bit in the serial tree),
and the ioctl handling in the dgrp driver having been done slightly
differently (staging tree got that one right, and removed both
TIOCGSOFTCAR and TIOCSSOFTCAR).
* tag 'tty-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (146 commits)
staging: sb105x: fix potential NULL pointer dereference in mp_chars_in_buffer()
staging/fwserial: Remove superfluous free
staging/fwserial: Use WARN_ONCE when port table is corrupted
staging/fwserial: Destruct embedded tty_port on teardown
staging/fwserial: Fix build breakage when !CONFIG_BUG
staging: fwserial: Add TTY-over-Firewire serial driver
drivers/tty/serial/serial_core.c: clean up HIGH_BITS_OFFSET usage
staging: dgrp: dgrp_tty.c: Audit the return values of get/put_user()
staging: dgrp: dgrp_tty.c: Remove the TIOCSSOFTCAR ioctl handler from dgrp driver
serial: ifx6x60: Add modem power off function in the platform reboot process
serial: mxs-auart: unmap the scatter list before we copy the data
serial: mxs-auart: disable the Receive Timeout Interrupt when DMA is enabled
serial: max310x: Setup missing "can_sleep" field for GPIO
tty/serial: fix ifx6x60.c declaration warning
serial: samsung: add devicetree properties for non-Exynos SoCs
serial: samsung: fix potential soft lockup during uart write
tty: vt: Remove redundant null check before kfree.
tty/8250 Add check for pci_ioremap_bar failure
tty/8250 Add support for Commtech's Fastcom Async-335 and Fastcom Async-PCIe cards
tty/8250 Add XR17D15x devices to the exar_handle_irq override
...
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/ccg/u_serial.c | 5 | ||||
-rw-r--r-- | drivers/staging/dgrp/dgrp_common.h | 1 | ||||
-rw-r--r-- | drivers/staging/dgrp/dgrp_driver.c | 4 | ||||
-rw-r--r-- | drivers/staging/dgrp/dgrp_net_ops.c | 73 | ||||
-rw-r--r-- | drivers/staging/dgrp/dgrp_specproc.c | 4 | ||||
-rw-r--r-- | drivers/staging/dgrp/dgrp_sysfs.c | 18 | ||||
-rw-r--r-- | drivers/staging/dgrp/dgrp_tty.c | 24 | ||||
-rw-r--r-- | drivers/staging/fwserial/fwserial.c | 17 | ||||
-rw-r--r-- | drivers/staging/sb105x/Kconfig | 9 | ||||
-rw-r--r-- | drivers/staging/sb105x/Makefile | 3 | ||||
-rw-r--r-- | drivers/staging/sb105x/sb_mp_register.h | 295 | ||||
-rw-r--r-- | drivers/staging/sb105x/sb_pci_mp.c | 3196 | ||||
-rw-r--r-- | drivers/staging/sb105x/sb_pci_mp.h | 293 | ||||
-rw-r--r-- | drivers/staging/sb105x/sb_ser_core.h | 368 |
16 files changed, 4203 insertions, 110 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 943ca607200..329bdb42109 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -138,6 +138,8 @@ source "drivers/staging/imx-drm/Kconfig" source "drivers/staging/dgrp/Kconfig" +source "drivers/staging/sb105x/Kconfig" + source "drivers/staging/fwserial/Kconfig" endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 20c764d7ab3..c7ec486680f 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -61,4 +61,5 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ obj-$(CONFIG_CED1401) += ced1401/ obj-$(CONFIG_DRM_IMX) += imx-drm/ obj-$(CONFIG_DGRP) += dgrp/ +obj-$(CONFIG_SB105X) += sb105x/ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c index 5b3f5fffea9..373c40656b5 100644 --- a/drivers/staging/ccg/u_serial.c +++ b/drivers/staging/ccg/u_serial.c @@ -1140,8 +1140,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count) return status; fail: - while (count--) + while (count--) { + tty_port_destroy(&ports[count].port->port); kfree(ports[count].port); + } put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; @@ -1195,6 +1197,7 @@ void gserial_cleanup(void) WARN_ON(port->port_usb != NULL); + tty_port_destroy(&port->port); kfree(port); } n_ports = 0; diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h index 05ff338471a..0583fe9c7b0 100644 --- a/drivers/staging/dgrp/dgrp_common.h +++ b/drivers/staging/dgrp/dgrp_common.h @@ -31,7 +31,6 @@ * All global storage allocation. ************************************************************************/ -extern int dgrp_rawreadok; /* Allow raw writing of input */ extern int dgrp_register_cudevices; /* enable legacy cu devices */ extern int dgrp_register_prdevices; /* enable transparent print devices */ extern int dgrp_poll_tick; /* Poll interval - in ms */ diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c index 6e4a0ebc074..aa262588e9b 100644 --- a/drivers/staging/dgrp/dgrp_driver.c +++ b/drivers/staging/dgrp/dgrp_driver.c @@ -39,14 +39,10 @@ MODULE_VERSION(DIGI_VERSION); struct list_head nd_struct_list; struct dgrp_poll_data dgrp_poll_data; -int dgrp_rawreadok = 1; /* Bypass flipbuf on input */ int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */ int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */ int dgrp_poll_tick = 20; /* Poll interval - in ms */ -module_param_named(rawreadok, dgrp_rawreadok, int, 0644); -MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input"); - module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644); MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices"); diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index c409cd03e8c..2d1bbfd5b67 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -151,20 +151,15 @@ static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf, * Copys the rbuf to the flipbuf and sends to line discipline. * Sends input buffer data to the line discipline. * - * There are several modes to consider here: - * rawreadok, tty->real_raw, and IF_PARMRK */ static void dgrp_input(struct ch_struct *ch) { struct nd_struct *nd; struct tty_struct *tty; - int remain; int data_len; int len; - int flip_len; int tty_count; ulong lock_flags; - struct tty_ldisc *ld; u8 *myflipbuf; u8 *myflipflagbuf; @@ -212,37 +207,11 @@ static void dgrp_input(struct ch_struct *ch) spin_unlock_irqrestore(&nd->nd_lock, lock_flags); - /* Decide how much data we can send into the tty layer */ - if (dgrp_rawreadok && tty->real_raw) - flip_len = MYFLIPLEN; - else - flip_len = TTY_FLIPBUF_SIZE; - /* data_len should be the number of chars that we read in */ data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; - remain = data_len; /* len is the amount of data we are going to transfer here */ - len = min(data_len, flip_len); - - /* take into consideration length of ldisc */ - len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt); - - ld = tty_ldisc_ref(tty); - - /* - * If we were unable to get a reference to the ld, - * don't flush our buffer, and act like the ld doesn't - * have any space to put the data right now. - */ - if (!ld) { - len = 0; - } else if (!ld->ops->receive_buf) { - spin_lock_irqsave(&nd->nd_lock, lock_flags); - ch->ch_rout = ch->ch_rin; - spin_unlock_irqrestore(&nd->nd_lock, lock_flags); - len = 0; - } + len = tty_buffer_request_room(tty, data_len); /* Check DPA flow control */ if ((nd->nd_dpa_debug) && @@ -254,42 +223,22 @@ static void dgrp_input(struct ch_struct *ch) dgrp_read_data_block(ch, myflipbuf, len); - /* - * In high performance mode, we don't have to update - * flag_buf or any of the counts or pointers into flip buf. - */ - if (!dgrp_rawreadok || !tty->real_raw) { - if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) - parity_scan(ch, myflipbuf, myflipflagbuf, &len); - else - memset(myflipflagbuf, TTY_NORMAL, len); - } + if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) + parity_scan(ch, myflipbuf, myflipflagbuf, &len); + else + memset(myflipflagbuf, TTY_NORMAL, len); if ((nd->nd_dpa_debug) && (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) dgrp_dpa_data(nd, 1, myflipbuf, len); - /* - * If we're doing raw reads, jam it right into the - * line disc bypassing the flip buffers. - */ - if (dgrp_rawreadok && tty->real_raw) - ld->ops->receive_buf(tty, myflipbuf, NULL, len); - else { - len = tty_buffer_request_room(tty, len); - tty_insert_flip_string_flags(tty, myflipbuf, - myflipflagbuf, len); - - /* Tell the tty layer its okay to "eat" the data now */ - tty_flip_buffer_push(tty); - } + tty_insert_flip_string_flags(tty, myflipbuf, + myflipflagbuf, len); + tty_flip_buffer_push(tty); ch->ch_rxcount += len; } - if (ld) - tty_ldisc_deref(ld); - /* * Wake up any sleepers (maybe dgrp close) that might be waiting * for a channel flag state change. @@ -2549,7 +2498,7 @@ data: /* * Fabricate and insert a data packet header to - * preceed the remaining data when it comes in. + * preced the remaining data when it comes in. */ if (remain < plen) { @@ -2718,7 +2667,7 @@ data: } /* - * Handle delayed response arrival preceeding + * Handle delayed response arrival preceding * the open response we are waiting for. */ @@ -3556,7 +3505,7 @@ void dgrp_poll_handler(unsigned long arg) /* * Decrement statistics. These are only for use with * KME, so don't worry that the operations are done - * unlocked, and so the results are occassionally wrong. + * unlocked, and so the results are occasionally wrong. */ nd->nd_read_count -= (nd->nd_read_count + diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index 24327c3bad8..c214078a89e 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c @@ -629,8 +629,6 @@ static int info_proc_show(struct seq_file *m, void *v) { seq_printf(m, "version: %s\n", DIGI_VERSION); seq_puts(m, "register_with_sysfs: 1\n"); - seq_printf(m, "rawreadok: 0x%08x\t(%d)\n", - dgrp_rawreadok, dgrp_rawreadok); seq_printf(m, "pollrate: 0x%08x\t(%d)\n", dgrp_poll_tick, dgrp_poll_tick); @@ -754,6 +752,8 @@ static int dgrp_add_id(long id) return 0; + /* FIXME this guy should free the tty driver stored in nd and destroy + * all channel ports */ error_out: kfree(nd); return ret; diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c index 43ab9f4d934..be179adfb7c 100644 --- a/drivers/staging/dgrp/dgrp_sysfs.c +++ b/drivers/staging/dgrp/dgrp_sysfs.c @@ -54,23 +54,6 @@ static DEVICE_ATTR(register_with_sysfs, 0400, dgrp_class_register_with_sysfs_show, NULL); -static ssize_t dgrp_class_rawreadok_show(struct device *c, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok); -} -static ssize_t dgrp_class_rawreadok_store(struct device *c, - struct device_attribute *attr, - const char *buf, size_t count) -{ - sscanf(buf, "0x%x\n", &dgrp_rawreadok); - return count; -} -static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show, - dgrp_class_rawreadok_store); - - static ssize_t dgrp_class_pollrate_show(struct device *c, struct device_attribute *attr, char *buf) @@ -90,7 +73,6 @@ static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show, static struct attribute *dgrp_sysfs_global_settings_entries[] = { &dev_attr_pollrate.attr, - &dev_attr_rawreadok.attr, &dev_attr_register_with_sysfs.attr, NULL }; diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index efa62ced7c8..51d3ed3dca2 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c @@ -432,7 +432,7 @@ static void drp_param(struct ch_struct *ch) /* * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE} * is defined for the terminal device file, and the value - * of one of the changable special control characters (see + * of one of the changeable special control characters (see * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be * disabled, that is, no input data shall be recognized as * the disabled special character." @@ -2265,9 +2265,7 @@ static int get_modem_info(struct ch_struct *ch, unsigned int *value) | ((mlast & DM_RI) ? TIOCM_RNG : 0) | ((mlast & DM_DSR) ? TIOCM_DSR : 0) | ((mlast & DM_CTS) ? TIOCM_CTS : 0); - put_user(mlast, (unsigned int __user *) value); - - return 0; + return put_user(mlast, (unsigned int __user *) value); } /* @@ -2285,7 +2283,8 @@ static int set_modem_info(struct ch_struct *ch, unsigned int command, if (error == 0) return -EFAULT; - get_user(arg, (unsigned int __user *) value); + if (get_user(arg, (unsigned int __user *) value)) + return -EFAULT; mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0) | ((arg & TIOCM_DTR) ? DM_DTR : 0); @@ -2684,7 +2683,7 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, - looking at the tty_ioctl code, these command all call our tty_set_termios at the driver's end, when a TCSETA* is sent, it is expecting the tty to have a termio structure, - NOT a termios stucture. These two structures differ in size + NOT a termios structure. These two structures differ in size and the tty_ioctl code does a conversion before processing them both. - we should treat the TCSETAW TCSETAF ioctls the same, and let the tty_ioctl code do the conversion stuff. @@ -2836,17 +2835,16 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, break; case DIGI_GETCUSTOMBAUD: - rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int)); - if (rc == 0) + if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg)) return -EFAULT; - put_user(ch->ch_custom_speed, (unsigned int __user *) arg); break; case DIGI_SETCUSTOMBAUD: { int new_rate; - get_user(new_rate, (unsigned int __user *) arg); + if (get_user(new_rate, (unsigned int __user *) arg)) + return -EFAULT; dgrp_set_custom_speed(ch, new_rate); break; @@ -2981,7 +2979,7 @@ static void dgrp_tty_start(struct tty_struct *tty) } /* - * Stop the reciever + * Stop the receiver */ static void dgrp_tty_input_stop(struct tty_struct *tty) { @@ -3104,6 +3102,7 @@ static void dgrp_tty_hangup(struct tty_struct *tty) void dgrp_tty_uninit(struct nd_struct *nd) { + unsigned int i; char id[3]; ID_TO_CHAR(nd->nd_ID, id); @@ -3137,6 +3136,8 @@ dgrp_tty_uninit(struct nd_struct *nd) put_tty_driver(nd->nd_xprint_ttdriver); nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG; } + for (i = 0; i < CHAN_MAX; i++) + tty_port_destroy(&nd->nd_chan[i].port); } @@ -3320,7 +3321,6 @@ dgrp_tty_init(struct nd_struct *nd) init_waitqueue_head(&(ch->ch_pun.un_open_wait)); init_waitqueue_head(&(ch->ch_pun.un_close_wait)); tty_port_init(&ch->port); - tty_port_init(&ch->port); } return 0; } diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 5d4d64a3ea8..61ee29083b2 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -939,14 +939,9 @@ static void fwserial_destroy(struct kref *kref) mutex_lock(&port_table_lock); for (j = 0; j < num_ports; ++i, ++j) { - static bool once; - int corrupt = port_table[i] != ports[j]; - if (corrupt && !once) { - WARN(corrupt, "port_table[%d]: %p != ports[%d]: %p", - i, port_table[i], j, ports[j]); - once = true; - port_table_corrupt = true; - } + port_table_corrupt |= port_table[i] != ports[j]; + WARN_ONCE(port_table_corrupt, "port_table[%d]: %p != ports[%d]: %p", + i, port_table[i], j, ports[j]); port_table[i] = NULL; } @@ -954,7 +949,7 @@ static void fwserial_destroy(struct kref *kref) for (j = 0; j < num_ports; ++j) { fw_core_remove_address_handler(&ports[j]->rx_handler); - dma_fifo_free(&ports[j]->tx_fifo); + tty_port_destroy(&ports[j]->port); kfree(ports[j]); } kfree(serial); @@ -2369,8 +2364,10 @@ unregister_ttys: return err; free_ports: - for (--i; i >= 0; --i) + for (--i; i >= 0; --i) { + tty_port_destroy(&serial->ports[i]->port); kfree(serial->ports[i]); + } kfree(serial); return err; } diff --git a/drivers/staging/sb105x/Kconfig b/drivers/staging/sb105x/Kconfig new file mode 100644 index 00000000000..ac87c5e38de --- /dev/null +++ b/drivers/staging/sb105x/Kconfig @@ -0,0 +1,9 @@ +config SB105X + tristate "SystemBase PCI Multiport UART" + select SERIAL_CORE + depends on PCI + help + A driver for the SystemBase Multi-2/PCI serial card + + To compile this driver a module, choose M here: the module + will be called "sb105x". diff --git a/drivers/staging/sb105x/Makefile b/drivers/staging/sb105x/Makefile new file mode 100644 index 00000000000..b1bf3779aca --- /dev/null +++ b/drivers/staging/sb105x/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_SB105X) += sb105x.o + +sb105x-y := sb_pci_mp.o diff --git a/drivers/staging/sb105x/sb_mp_register.h b/drivers/staging/sb105x/sb_mp_register.h new file mode 100644 index 00000000000..5480ae11368 --- /dev/null +++ b/drivers/staging/sb105x/sb_mp_register.h @@ -0,0 +1,295 @@ + +/* + * SB105X_UART.h + * + * Copyright (C) 2008 systembase + * + * UART registers. + * + * 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. + */ + +#ifndef UART_SB105X_H +#define UART_SB105X_H + +/* + * option register + */ + +/* Device Infomation Register */ +#define MP_OPTR_DIR0 0x04 /* port0 ~ port8 */ +#define MP_OPTR_DIR1 0x05 /* port8 ~ port15 */ +#define MP_OPTR_DIR2 0x06 /* port16 ~ port23 */ +#define MP_OPTR_DIR3 0x07 /* port24 ~ port31 */ + +#define DIR_UART_16C550 0 +#define DIR_UART_16C1050 1 +#define DIR_UART_16C1050A 2 + +#define DIR_CLK_1843200 0x0 /* input clock 1843200 Hz */ +#define DIR_CLK_3686400 0x1 /* input clock 3686400 Hz */ +#define DIR_CLK_7372800 0x2 /* input clock 7372800 Hz */ +#define DIR_CLK_14745600 0x3 /* input clock 14745600 Hz */ +#define DIR_CLK_29491200 0x4 /* input clock 29491200 Hz */ +#define DIR_CLK_58985400 0x5 /* input clock 58985400 Hz */ + +/* Interface Information Register */ +#define MP_OPTR_IIR0 0x08 /* port0 ~ port8 */ +#define MP_OPTR_IIR1 0x09 /* port8 ~ port15 */ +#define MP_OPTR_IIR2 0x0A /* port16 ~ port23 */ +#define MP_OPTR_IIR3 0x0B /* port24 ~ port31 */ + +#define IIR_RS232 0x00 /* RS232 type */ +#define IIR_RS422 0x10 /* RS422 type */ +#define IIR_RS485 0x20 /* RS485 type */ +#define IIR_UNKNOWN 0x30 /* unknown type */ + +/* Interrrupt Mask Register */ +#define MP_OPTR_IMR0 0x0C /* port0 ~ port8 */ +#define MP_OPTR_IMR1 0x0D /* port8 ~ port15 */ +#define MP_OPTR_IMR2 0x0E /* port16 ~ port23 */ +#define MP_OPTR_IMR3 0x0F /* port24 ~ port31 */ + +/* Interrupt Poll Register */ +#define MP_OPTR_IPR0 0x10 /* port0 ~ port8 */ +#define MP_OPTR_IPR1 0x11 /* port8 ~ port15 */ +#define MP_OPTR_IPR2 0x12 /* port16 ~ port23 */ +#define MP_OPTR_IPR3 0x13 /* port24 ~ port31 */ + +/* General Purpose Output Control Register */ +#define MP_OPTR_GPOCR 0x20 + +/* General Purpose Output Data Register */ +#define MP_OPTR_GPODR 0x21 + +/* Parallel Additional Function Register */ +#define MP_OPTR_PAFR 0x23 + +/* + * systembase 16c105x UART register + */ + +#define PAGE_0 0 +#define PAGE_1 1 +#define PAGE_2 2 +#define PAGE_3 3 +#define PAGE_4 4 + +/* + * ****************************************************************** + * * DLAB=0 =============== Page 0 Registers * + * ****************************************************************** + */ + +#define SB105X_RX 0 /* In: Receive buffer */ +#define SB105X_TX 0 /* Out: Transmit buffer */ + +#define SB105X_IER 1 /* Out: Interrupt Enable Register */ + +#define SB105X_IER_CTSI 0x80 /* CTS# Interrupt Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_RTSI 0x40 /* RTS# Interrupt Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_XOI 0x20 /* Xoff Interrupt Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_SME 0x10 /* Sleep Mode Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_MSI 0x08 /* Enable Modem status interrupt */ +#define SB105X_IER_RLSI 0x04 /* Enable receiver line status interrupt */ +#define SB105X_IER_THRI 0x02 /* Enable Transmitter holding register int. */ +#define SB105X_IER_RDI 0x01 /* Enable receiver data interrupt */ + +#define SB105X_ISR 2 /* In: Interrupt ID Register */ + +#define SB105X_ISR_NOINT 0x01 /* No interrupts pending */ +#define SB105X_ISR_RLSI 0x06 /* Receiver line status interrupt (Priority = 1)*/ +#define SB105X_ISR_RDAI 0x0c /* Receive Data Available interrupt */ +#define SB105X_ISR_CTII 0x04 /* Character Timeout Indication interrupt */ +#define SB105X_ISR_THRI 0x02 /* Transmitter holding register empty */ +#define SB105X_ISR_MSI 0x00 /* Modem status interrupt */ +#define SB105X_ISR_RXCI 0x10 /* Receive Xoff or Special Character interrupt */ +#define SB105X_ISR_RCSI 0x20 /* RTS#, CTS# status interrupt during Auto RTS/CTS flow control */ + +#define SB105X_FCR 2 /* Out: FIFO Control Register */ + +#define SB105X_FCR_FEN 0x01 /* FIFO Enable */ +#define SB105X_FCR_RXFR 0x02 /* RX FIFO Reset */ +#define SB105X_FCR_TXFR 0x04 /* TX FIFO Reset */ +#define SB105X_FCR_DMS 0x08 /* DMA Mode Select */ + +#define SB105X_FCR_RTR08 0x00 /* Receice Trigger Level set at 8 */ +#define SB105X_FCR_RTR16 0x40 /* Receice Trigger Level set at 16 */ +#define SB105X_FCR_RTR56 0x80 /* Receice Trigger Level set at 56 */ +#define SB105X_FCR_RTR60 0xc0 /* Receice Trigger Level set at 60 */ +#define SB105X_FCR_TTR08 0x00 /* Transmit Trigger Level set at 8 */ +#define SB105X_FCR_TTR16 0x10 /* Transmit Trigger Level set at 16 */ +#define SB105X_FCR_TTR32 0x20 /* Transmit Trigger Level set at 32 */ +#define SB105X_FCR_TTR56 0x30 /* Transmit Trigger Level set at 56 */ + +#define SB105X_LCR 3 /* Out: Line Control Register */ +/* + * * Note: if the word length is 5 bits (SB105X_LCR_WLEN5), then setting + * * SB105X_LCR_STOP will select 1.5 stop bits, not 2 stop bits. + */ +#define SB105X_LCR_DLAB 0x80 /* Divisor Latch Enable */ +#define SB105X_LCR_SBC 0x40 /* Break Enable*/ +#define SB105X_LCR_SPAR 0x20 /* Set Stick parity */ +#define SB105X_LCR_EPAR 0x10 /* Even parity select */ +#define SB105X_LCR_PAREN 0x08 /* Parity Enable */ +#define SB105X_LCR_STOP 0x04 /* Stop bits: 0->1 bit, 1->2 bits, 1 and SB105X_LCR_WLEN5 -> 1.5 bit */ +#define SB105X_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ +#define SB105X_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ +#define SB105X_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ +#define SB105X_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ + +#define SB105X_LCR_BF 0xBF + +#define SB105X_MCR 4 /* Out: Modem Control Register */ +#define SB105X_MCR_CPS 0x80 /* Clock Prescaler Select */ +#define SB105X_MCR_P2S 0x40 /* Page 2 Select /Xoff Re-Transmit Access Enable */ +#define SB105X_MCR_XOA 0x20 /* Xon Any Enable */ +#define SB105X_MCR_ILB 0x10 /* Internal Loopback Enable */ +#define SB105X_MCR_OUT2 0x08 /* Out2/Interrupt Output Enable*/ +#define SB105X_MCR_OUT1 0x04 /* Out1/Interrupt Output Enable */ +#define SB105X_MCR_RTS 0x02 /* RTS# Output */ +#define SB105X_MCR_DTR 0x01 /* DTR# Output */ + +#define SB105X_LSR 5 /* In: Line Status Register */ +#define SB105X_LSR_RFEI 0x80 /* Receive FIFO data error Indicator */ +#define SB105X_LSR_TEMI 0x40 /* THR and TSR Empty Indicator */ +#define SB105X_LSR_THRE 0x20 /* THR Empty Indicator */ +#define SB105X_LSR_BII 0x10 /* Break interrupt indicator */ +#define SB105X_LSR_FEI 0x08 /* Frame error indicator */ +#define SB105X_LSR_PEI 0x04 /* Parity error indicator */ +#define SB105X_LSR_OEI 0x02 /* Overrun error indicator */ +#define SB105X_LSR_RDRI 0x01 /* Receive data ready Indicator*/ + +#define SB105X_MSR 6 /* In: Modem Status Register */ +#define SB105X_MSR_DCD 0x80 /* Data Carrier Detect */ +#define SB105X_MSR_RI 0x40 /* Ring Indicator */ +#define SB105X_MSR_DSR 0x20 /* Data Set Ready */ +#define SB105X_MSR_CTS 0x10 /* Clear to Send */ +#define SB105X_MSR_DDCD 0x08 /* Delta DCD */ +#define SB105X_MSR_DRI 0x04 /* Delta ring indicator */ +#define SB105X_MSR_DDSR 0x02 /* Delta DSR */ +#define SB105X_MSR_DCTS 0x01 /* Delta CTS */ + +#define SB105XA_MDR 6 /* Out: Multi Drop mode Register */ +#define SB105XA_MDR_NPS 0x08 /* 9th Bit Polarity Select */ +#define SB105XA_MDR_AME 0x02 /* Auto Multi-drop Enable */ +#define SB105XA_MDR_MDE 0x01 /* Multi Drop Enable */ + +#define SB105X_SPR 7 /* I/O: Scratch Register */ + +/* + * DLAB=1 + */ +#define SB105X_DLL 0 /* Out: Divisor Latch Low */ +#define SB105X_DLM 1 /* Out: Divisor Latch High */ + +/* + * ****************************************************************** + * * DLAB(LCR[7]) = 0 , MCR[6] = 1 ============= Page 2 Registers * + * ****************************************************************** + */ +#define SB105X_GICR 1 /* Global Interrupt Control Register */ +#define SB105X_GICR_GIM 0x01 /* Global Interrupt Mask */ + +#define SB105X_GISR 2 /* Global Interrupt Status Register */ +#define SB105X_GISR_MGICR0 0x80 /* Mirror the content of GICR[0] */ +#define SB105X_GISR_CS3IS 0x08 /* SB105X of CS3# Interrupt Status */ +#define SB105X_GISR_CS2IS 0x04 /* SB105X of CS2# Interrupt Status */ +#define SB105X_GISR_CS1IS 0x02 /* SB105X of CS1# Interrupt Status */ +#define SB105X_GISR_CS0IS 0x01 /* SB105X of CS0# Interrupt Status */ + +#define SB105X_TFCR 5 /* Transmit FIFO Count Register */ + +#define SB105X_RFCR 6 /* Receive FIFO Count Register */ + +#define SB105X_FSR 7 /* Flow Control Status Register */ +#define SB105X_FSR_THFS 0x20 /* Transmit Hardware Flow Control Status */ +#define SB105X_FSR_TSFS 0x10 /* Transmit Software Flow Control Status */ +#define SB105X_FSR_RHFS 0x02 /* Receive Hardware Flow Control Status */ +#define SB105X_FSR_RSFS 0x01 /* Receive Software Flow Control Status */ + +/* + * ****************************************************************** + * * LCR = 0xBF, PSR[0] = 0 ============= Page 3 Registers * + * ****************************************************************** + */ + +#define SB105X_PSR 0 /* Page Select Register */ +#define SB105X_PSR_P3KEY 0xA4 /* Page 3 Select Key */ +#define SB105X_PSR_P4KEY 0xA5 /* Page 5 Select Key */ + +#define SB105X_ATR 1 /* Auto Toggle Control Register */ +#define SB105X_ATR_RPS 0x80 /* RXEN Polarity Select */ +#define SB105X_ATR_RCMS 0x40 /* RXEN Control Mode Select */ +#define SB105X_ATR_TPS 0x20 /* TXEN Polarity Select */ +#define SB105X_ATR_TCMS 0x10 /* TXEN Control Mode Select */ +#define SB105X_ATR_ATDIS 0x00 /* Auto Toggle is disabled */ +#define SB105X_ATR_ART 0x01 /* RTS#/TXEN pin operates as TXEN */ +#define SB105X_ATR_ADT 0x02 /* DTR#/TXEN pin operates as TXEN */ +#define SB105X_ATR_A80 0x03 /* only in 80 pin use */ + +#define SB105X_EFR 2 /* (Auto) Enhanced Feature Register */ +#define SB105X_EFR_ACTS 0x80 /* Auto-CTS Flow Control Enable */ +#define SB105X_EFR_ARTS 0x40 /* Auto-RTS Flow Control Enable */ +#define SB105X_EFR_SCD 0x20 /* Special Character Detect */ +#define SB105X_EFR_EFBEN 0x10 /* Enhanced Function Bits Enable */ + +#define SB105X_XON1 4 /* Xon1 Character Register */ +#define SB105X_XON2 5 /* Xon2 Character Register */ +#define SB105X_XOFF1 6 /* Xoff1 Character Register */ +#define SB105X_XOFF2 7 /* Xoff2 Character Register */ + +/* + * ****************************************************************** + * * LCR = 0xBF, PSR[0] = 1 ============ Page 4 Registers * + * ****************************************************************** + */ + +#define SB105X_AFR 1 /* Additional Feature Register */ +#define SB105X_AFR_GIPS 0x20 /* Global Interrupt Polarity Select */ +#define SB105X_AFR_GIEN 0x10 /* Global Interrupt Enable */ +#define SB105X_AFR_AFEN 0x01 /* 256-byte FIFO Enable */ + +#define SB105X_XRCR 2 /* Xoff Re-transmit Count Register */ +#define SB105X_XRCR_NRC1 0x00 /* Transmits Xoff Character whenever the number of received data is 1 during XOFF status */ +#define SB105X_XRCR_NRC4 0x01 /* Transmits Xoff Character whenever the number of received data is 4 during XOFF status */ +#define SB105X_XRCR_NRC8 0x02 /* Transmits Xoff Character whenever the number of received data is 8 during XOFF status */ +#define SB105X_XRCR_NRC16 0x03 /* Transmits Xoff Character whenever the number of received data is 16 during XOFF status */ + +#define SB105X_TTR 4 /* Transmit FIFO Trigger Level Register */ +#define SB105X_RTR 5 /* Receive FIFO Trigger Level Register */ +#define SB105X_FUR 6 /* Flow Control Upper Threshold Register */ +#define SB105X_FLR 7 /* Flow Control Lower Threshold Register */ + + +/* page 0 */ + +#define SB105X_GET_CHAR(port) inb((port)->iobase + SB105X_RX) +#define SB105X_GET_IER(port) inb((port)->iobase + SB105X_IER) +#define SB105X_GET_ISR(port) inb((port)->iobase + SB105X_ISR) +#define SB105X_GET_LCR(port) inb((port)->iobase + SB105X_LCR) +#define SB105X_GET_MCR(port) inb((port)->iobase + SB105X_MCR) +#define SB105X_GET_LSR(port) inb((port)->iobase + SB105X_LSR) +#define SB105X_GET_MSR(port) inb((port)->iobase + SB105X_MSR) +#define SB105X_GET_SPR(port) inb((port)->iobase + SB105X_SPR) + +#define SB105X_PUT_CHAR(port,v) outb((v),(port)->iobase + SB105X_TX ) +#define SB105X_PUT_IER(port,v) outb((v),(port)->iobase + SB105X_IER ) +#define SB105X_PUT_FCR(port,v) outb((v),(port)->iobase + SB105X_FCR ) +#define SB105X_PUT_LCR(port,v) outb((v),(port)->iobase + SB105X_LCR ) +#define SB105X_PUT_MCR(port,v) outb((v),(port)->iobase + SB105X_MCR ) +#define SB105X_PUT_SPR(port,v) outb((v),(port)->iobase + SB105X_SPR ) + + +/* page 1 */ +#define SB105X_GET_REG(port,reg) inb((port)->iobase + (reg)) +#define SB105X_PUT_REG(port,reg,v) outb((v),(port)->iobase + (reg)) + +/* page 2 */ + +#define SB105X_PUT_PSR(port,v) outb((v),(port)->iobase + SB105X_PSR ) + +#endif diff --git a/drivers/staging/sb105x/sb_pci_mp.c b/drivers/staging/sb105x/sb_pci_mp.c new file mode 100644 index 00000000000..edb2a85b9d5 --- /dev/null +++ b/drivers/staging/sb105x/sb_pci_mp.c @@ -0,0 +1,3196 @@ +#include "sb_pci_mp.h" +#include <linux/module.h> +#include <linux/parport.h> + +extern struct parport *parport_pc_probe_port(unsigned long base_lo, + unsigned long base_hi, + int irq, int dma, + struct device *dev, + int irqflags); + +static struct mp_device_t mp_devs[MAX_MP_DEV]; +static int mp_nrpcibrds = sizeof(mp_pciboards)/sizeof(mppcibrd_t); +static int NR_BOARD=0; +static int NR_PORTS=0; +static struct mp_port multi_ports[MAX_MP_PORT]; +static struct irq_info irq_lists[NR_IRQS]; + +static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset); +static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value); +static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset); +static int sb1054_get_register(struct sb_uart_port * port, int page, int reg); +static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value); +static void SendATCommand(struct mp_port * mtpt); +static int set_deep_fifo(struct sb_uart_port * port, int status); +static int get_deep_fifo(struct sb_uart_port * port); +static int get_device_type(int arg); +static int set_auto_rts(struct sb_uart_port *port, int status); +static void mp_stop(struct tty_struct *tty); +static void __mp_start(struct tty_struct *tty); +static void mp_start(struct tty_struct *tty); +static void mp_tasklet_action(unsigned long data); +static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear); +static int mp_startup(struct sb_uart_state *state, int init_hw); +static void mp_shutdown(struct sb_uart_state *state); +static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios); + +static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c); +static int mp_put_char(struct tty_struct *tty, unsigned char ch); + +static void mp_put_chars(struct tty_struct *tty); +static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count); +static int mp_write_room(struct tty_struct *tty); +static int mp_chars_in_buffer(struct t |