Commit 7f02ab3c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (25 commits)
  serial: Tidy REMOTE_DEBUG
  serial: isicomm: handle running out of slots
  serial: bfin_sport_uart: Use resource size to fix off-by-one error
  tty: fix obsolete comment on tty_insert_flip_string_fixed_flag
  serial: Add driver for the Altera UART
  serial: Add driver for the Altera JTAG UART
  serial: timbuart: make sure last byte is sent when port is closed
  serial: two branches the same in timbuart_set_mctrl()
  serial: uartlite: move from byte accesses to word accesses
  tty: n_gsm: depends on NET
  tty: n_gsm line discipline
  serial: TTY: new ldiscs for staging
  serial: bfin_sport_uart: drop redundant cpu depends
  serial: bfin_sport_uart: drop the experimental markings
  serial: bfin_sport_uart: pull in bfin_sport.h for SPORT defines
  serial: bfin_sport_uart: only enable SPORT TX if data is to be sent
  serial: bfin_sport_uart: drop useless status masks
  serial: bfin_sport_uart: zero sport_uart_port if allocated dynamically
  serial: bfin_sport_uart: protect changes to uart_port
  serial: bfin_sport_uart: add support for CTS/RTS via GPIOs
  ...
parents d6fb1db0 0dbb5671
......@@ -276,11 +276,19 @@ config N_HDLC
Allows synchronous HDLC communications with tty device drivers that
support synchronous HDLC such as the Microgate SyncLink adapter.
This driver can only be built as a module ( = code which can be
This driver can be built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called n_hdlc. If you want to do that, say M
here.
config N_GSM
tristate "GSM MUX line discipline support (EXPERIMENTAL)"
depends on EXPERIMENTAL
depends on NET
help
This line discipline provides support for the GSM MUX protocol and
presents the mux as a set of 61 individual tty devices.
config RISCOM8
tristate "SDL RISCom/8 card support"
depends on SERIAL_NONSTANDARD
......
......@@ -40,6 +40,7 @@ obj-$(CONFIG_SYNCLINK) += synclink.o
obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
obj-$(CONFIG_N_HDLC) += n_hdlc.o
obj-$(CONFIG_N_GSM) += n_gsm.o
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
obj-$(CONFIG_SX) += sx.o generic_serial.o
obj-$(CONFIG_RIO) += rio/ generic_serial.o
......
......@@ -1573,11 +1573,16 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
/* allot the first empty slot in the array */
for (index = 0; index < BOARD_COUNT; index++)
for (index = 0; index < BOARD_COUNT; index++) {
if (isi_card[index].base == 0) {
board = &isi_card[index];
break;
}
}
if (index == BOARD_COUNT) {
retval = -ENODEV;
goto err_disable;
}
board->index = index;
board->base = pci_resource_start(pdev, 3);
......@@ -1624,6 +1629,7 @@ errunrr:
errdec:
board->base = 0;
card_count--;
err_disable:
pci_disable_device(pdev);
err:
return retval;
......
This diff is collapsed.
......@@ -176,23 +176,6 @@ static void config_setup(struct cyclades_port *);
static void show_status(int);
#endif
#ifdef CONFIG_REMOTE_DEBUG
static void debug_setup(void);
void queueDebugChar(int c);
int getDebugChar(void);
#define DEBUG_PORT 1
#define DEBUG_LEN 256
typedef struct {
int in;
int out;
unsigned char buf[DEBUG_LEN];
} debugq;
debugq debugiq;
#endif
/*
* I have my own version of udelay(), as it is needed when initialising
* the chip, before the delay loop has been calibrated. Should probably
......@@ -515,11 +498,6 @@ static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
/* determine the channel and change to that context */
channel = (u_short) (base_addr[CyLICR] >> 2);
#ifdef CONFIG_REMOTE_DEBUG
if (channel == DEBUG_PORT) {
panic("TxInt on debug port!!!");
}
#endif
/* validate the port number (as configured and open) */
if ((channel < 0) || (NR_PORTS <= channel)) {
base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
......@@ -634,14 +612,6 @@ static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
info->last_active = jiffies;
save_cnt = char_count = base_addr[CyRFOC];
#ifdef CONFIG_REMOTE_DEBUG
if (channel == DEBUG_PORT) {
while (char_count--) {
data = base_addr[CyRDR];
queueDebugChar(data);
}
} else
#endif
/* if there is nowhere to put the data, discard it */
if (info->tty == 0) {
while (char_count--) {
......@@ -2195,9 +2165,7 @@ static int __init serial167_init(void)
port_num++;
info++;
}
#ifdef CONFIG_REMOTE_DEBUG
debug_setup();
#endif
ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
"cd2401_errors", cd2401_rxerr_interrupt);
if (ret) {
......@@ -2518,193 +2486,4 @@ static int __init serial167_console_init(void)
console_initcall(serial167_console_init);
#ifdef CONFIG_REMOTE_DEBUG
void putDebugChar(int c)
{
volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
unsigned long flags;
volatile u_char sink;
u_char ier;
int port;
local_irq_save(flags);
/* Ensure transmitter is enabled! */
port = DEBUG_PORT;
base_addr[CyCAR] = (u_char) port;
while (base_addr[CyCCR])
;
base_addr[CyCCR] = CyENB_XMTR;
ier = base_addr[CyIER];
base_addr[CyIER] = CyTxMpty;
while (1) {
if (pcc2chip[PccSCCTICR] & 0x20) {
/* We have a Tx int. Acknowledge it */
sink = pcc2chip[PccTPIACKR];
if ((base_addr[CyLICR] >> 2) == port) {
base_addr[CyTDR] = c;
base_addr[CyTEOIR] = 0;
break;
} else
base_addr[CyTEOIR] = CyNOTRANS;
}
}
base_addr[CyIER] = ier;
local_irq_restore(flags);
}
int getDebugChar()
{
volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
unsigned long flags;
volatile u_char sink;
u_char ier;
int port;
int i, c;
i = debugiq.out;
if (i != debugiq.in) {
c = debugiq.buf[i];
if (++i == DEBUG_LEN)
i = 0;
debugiq.out = i;
return c;
}
/* OK, nothing in queue, wait in poll loop */
local_irq_save(flags);
/* Ensure receiver is enabled! */
port = DEBUG_PORT;
base_addr[CyCAR] = (u_char) port;
#if 0
while (base_addr[CyCCR])
;
base_addr[CyCCR] = CyENB_RCVR;
#endif
ier = base_addr[CyIER];
base_addr[CyIER] = CyRxData;
while (1) {
if (pcc2chip[PccSCCRICR] & 0x20) {
/* We have a Rx int. Acknowledge it */
sink = pcc2chip[PccRPIACKR];
if ((base_addr[CyLICR] >> 2) == port) {
int cnt = base_addr[CyRFOC];
while (cnt-- > 0) {
c = base_addr[CyRDR];
if (c == 0)
printk
("!! debug char is null (cnt=%d) !!",
cnt);
else
queueDebugChar(c);
}
base_addr[CyREOIR] = 0;
i = debugiq.out;
if (i == debugiq.in)
panic("Debug input queue empty!");
c = debugiq.buf[i];
if (++i == DEBUG_LEN)
i = 0;
debugiq.out = i;
break;
} else
base_addr[CyREOIR] = CyNOTRANS;
}
}
base_addr[CyIER] = ier;
local_irq_restore(flags);
return (c);
}
void queueDebugChar(int c)
{
int i;
i = debugiq.in;
debugiq.buf[i] = c;
if (++i == DEBUG_LEN)
i = 0;
if (i != debugiq.out)
debugiq.in = i;
}
static void debug_setup()
{
unsigned long flags;
volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
int i, cflag;
cflag = B19200;
local_irq_save(flags);
for (i = 0; i < 4; i++) {
base_addr[CyCAR] = i;
base_addr[CyLICR] = i << 2;
}
debugiq.in = debugiq.out = 0;
base_addr[CyCAR] = DEBUG_PORT;
/* baud rate */
i = cflag & CBAUD;
base_addr[CyIER] = 0;
base_addr[CyCMR] = CyASYNC;
base_addr[CyLICR] = DEBUG_PORT << 2;
base_addr[CyLIVR] = 0x5c;
/* tx and rx baud rate */
base_addr[CyTCOR] = baud_co[i];
base_addr[CyTBPR] = baud_bpr[i];
base_addr[CyRCOR] = baud_co[i] >> 5;
base_addr[CyRBPR] = baud_bpr[i];
/* set line characteristics according configuration */
base_addr[CySCHR1] = 0;
base_addr[CySCHR2] = 0;
base_addr[CySCRL] = 0;
base_addr[CySCRH] = 0;
base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
base_addr[CyCOR2] = 0;
base_addr[CyCOR3] = Cy_1_STOP;
base_addr[CyCOR4] = baud_cor4[i];
base_addr[CyCOR5] = 0;
base_addr[CyCOR6] = 0;
base_addr[CyCOR7] = 0;
write_cy_cmd(base_addr, CyINIT_CHAN);
write_cy_cmd(base_addr, CyENB_RCVR);
base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */
base_addr[CyRTPRL] = 2;
base_addr[CyRTPRH] = 0;
base_addr[CyMSVR1] = CyRTS;
base_addr[CyMSVR2] = CyDTR;
base_addr[CyIER] = CyRxData;
local_irq_restore(flags);
} /* debug_setup */
#endif
MODULE_LICENSE("GPL");
......@@ -238,7 +238,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
* @size: size
*
* Queue a series of bytes to the tty buffering. All the characters
* passed are marked as without error. Returns the number added.
* passed are marked with the supplied flag. Returns the number added.
*
* Locking: Called functions may take tty->buf.lock
*/
......
......@@ -1423,8 +1423,8 @@ config SERIAL_SC26XX_CONSOLE
Support for Console on SC2681/SC2692 serial ports.
config SERIAL_BFIN_SPORT
tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)"
depends on BLACKFIN && EXPERIMENTAL
tristate "Blackfin SPORT emulate UART"
depends on BLACKFIN
select SERIAL_CORE
help
Enable SPORT emulate UART on Blackfin series.
......@@ -1439,28 +1439,52 @@ config SERIAL_BFIN_SPORT_CONSOLE
config SERIAL_BFIN_SPORT0_UART
bool "Enable UART over SPORT0"
depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M)
depends on SERIAL_BFIN_SPORT && !(BF542 || BF544)
help
Enable UART over SPORT0
config SERIAL_BFIN_SPORT0_UART_CTSRTS
bool "Enable UART over SPORT0 hardware flow control"
depends on SERIAL_BFIN_SPORT0_UART
help
Enable hardware flow control in the driver.
config SERIAL_BFIN_SPORT1_UART
bool "Enable UART over SPORT1"
depends on SERIAL_BFIN_SPORT
help
Enable UART over SPORT1
config SERIAL_BFIN_SPORT1_UART_CTSRTS
bool "Enable UART over SPORT1 hardware flow control"
depends on SERIAL_BFIN_SPORT1_UART
help
Enable hardware flow control in the driver.
config SERIAL_BFIN_SPORT2_UART
bool "Enable UART over SPORT2"
depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539)
help
Enable UART over SPORT2
config SERIAL_BFIN_SPORT2_UART_CTSRTS
bool "Enable UART over SPORT2 hardware flow control"
depends on SERIAL_BFIN_SPORT2_UART
help
Enable hardware flow control in the driver.
config SERIAL_BFIN_SPORT3_UART
bool "Enable UART over SPORT3"
depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539)
help
Enable UART over SPORT3
config SERIAL_BFIN_SPORT3_UART_CTSRTS
bool "Enable UART over SPORT3 hardware flow control"
depends on SERIAL_BFIN_SPORT3_UART
help
Enable hardware flow control in the driver.
config SERIAL_TIMBERDALE
tristate "Support for timberdale UART"
select SERIAL_CORE
......@@ -1499,4 +1523,56 @@ config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
help
Support for running a console on the GRLIB APBUART
config SERIAL_ALTERA_JTAGUART
tristate "Altera JTAG UART support"
select SERIAL_CORE
help
This driver supports the Altera JTAG UART port.
config SERIAL_ALTERA_JTAGUART_CONSOLE
bool "Altera JTAG UART console support"
depends on SERIAL_ALTERA_JTAGUART=y
select SERIAL_CORE_CONSOLE
help
Enable a Altera JTAG UART port to be the system console.
config SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS
bool "Bypass output when no connection"
depends on SERIAL_ALTERA_JTAGUART_CONSOLE
select SERIAL_CORE_CONSOLE
help
Bypass console output and keep going even if there is no
JTAG terminal connection with the host.
config SERIAL_ALTERA_UART
tristate "Altera UART support"
select SERIAL_CORE
help
This driver supports the Altera softcore UART port.
config SERIAL_ALTERA_UART_MAXPORTS
int "Maximum number of Altera UART ports"
depends on SERIAL_ALTERA_UART
default 4
help
This setting lets you define the maximum number of the Altera
UART ports. The usual default varies from board to board, and
this setting is a way of catering for that.
config SERIAL_ALTERA_UART_BAUDRATE
int "Default baudrate for Altera UART ports"
depends on SERIAL_ALTERA_UART
default 115200
help
This setting lets you define what the default baudrate is for the
Altera UART ports. The usual default varies from board to board,
and this setting is a way of catering for that.
config SERIAL_ALTERA_UART_CONSOLE
bool "Altera UART console support"
depends on SERIAL_ALTERA_UART=y
select SERIAL_CORE_CONSOLE
help
Enable a Altera UART port to be the system console.
endmenu
......@@ -82,3 +82,5 @@ obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
/*
* altera_jtaguart.c -- Altera JTAG UART driver
*
* Based on mcf.c -- Freescale ColdFire UART driver
*
* (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
* (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw>
* (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch>
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/altera_jtaguart.h>
#define DRV_NAME "altera_jtaguart"
/*
* Altera JTAG UART register definitions according to the Altera JTAG UART
* datasheet: http://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf
*/
#define ALTERA_JTAGUART_SIZE 8
#define ALTERA_JTAGUART_DATA_REG 0
#define ALTERA_JTAGUART_DATA_DATA_MSK 0x000000FF
#define ALTERA_JTAGUART_DATA_RVALID_MSK 0x00008000
#define ALTERA_JTAGUART_DATA_RAVAIL_MSK 0xFFFF0000
#define ALTERA_JTAGUART_DATA_RAVAIL_OFF 16
#define ALTERA_JTAGUART_CONTROL_REG 4
#define ALTERA_JTAGUART_CONTROL_RE_MSK 0x00000001
#define ALTERA_JTAGUART_CONTROL_WE_MSK 0x00000002
#define ALTERA_JTAGUART_CONTROL_RI_MSK 0x00000100
#define ALTERA_JTAGUART_CONTROL_RI_OFF 8
#define ALTERA_JTAGUART_CONTROL_WI_MSK 0x00000200
#define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400
#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000
#define ALTERA_JTAGUART_CONTROL_WSPACE_OFF 16
/*
* Local per-uart structure.
*/
struct altera_jtaguart {
struct uart_port port;
unsigned int sigs; /* Local copy of line sigs */
unsigned long imr; /* Local IMR mirror */
};
static unsigned int altera_jtaguart_tx_empty(struct uart_port *port)
{
return (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) &
ALTERA_JTAGUART_CONTROL_WSPACE_MSK) ? TIOCSER_TEMT : 0;
}
static unsigned int altera_jtaguart_get_mctrl(struct uart_port *port)
{
return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
}
static void altera_jtaguart_set_mctrl(struct uart_port *port, unsigned int sigs)
{
}
static void altera_jtaguart_start_tx(struct uart_port *port)
{
struct altera_jtaguart *pp =
container_of(port, struct altera_jtaguart, port);
pp->imr |= ALTERA_JTAGUART_CONTROL_WE_MSK;
writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
}
static void altera_jtaguart_stop_tx(struct uart_port *port)
{
struct altera_jtaguart *pp =
container_of(port, struct altera_jtaguart, port);
pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK;
writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
}
static void altera_jtaguart_stop_rx(struct uart_port *port)
{
struct altera_jtaguart *pp =
container_of(port, struct altera_jtaguart, port);
pp->imr &= ~ALTERA_JTAGUART_CONTROL_RE_MSK;
writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
}
static void altera_jtaguart_break_ctl(struct uart_port *port, int break_state)
{
}
static void altera_jtaguart_enable_ms(struct uart_port *port)
{
}
static void altera_jtaguart_set_termios(struct uart_port *port,
struct ktermios *termios,
struct ktermios *old)
{
/* Just copy the old termios settings back */
if (old)
tty_termios_copy_hw(termios, old);
}
static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp)
{
struct uart_port *port = &pp->port;
unsigned char ch, flag;
unsigned long status;
while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) &
ALTERA_JTAGUART_DATA_RVALID_MSK) {
ch = status & ALTERA_JTAGUART_DATA_DATA_MSK;
flag = TTY_NORMAL;
port->icount.rx++;
if (uart_handle_sysrq_char(port, ch))
continue;
uart_insert_char(port, 0, 0, ch, flag);
}
tty_flip_buffer_push(port->state->port.tty);
}
static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp)
{
struct uart_port *port = &pp->port;
struct circ_buf *xmit = &port->state->xmit;
unsigned int pending, count;
if (port->x_char) {
/* Send special char - probably flow control */
writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG);
port->x_char = 0;
port->icount.tx++;
return;
}
pending = uart_circ_chars_pending(xmit);
if (pending > 0) {
count = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) &
ALTERA_JTAGUART_CONTROL_WSPACE_MSK) >>
ALTERA_JTAGUART_CONTROL_WSPACE_OFF;
if (count > pending)
count = pending;
if (count > 0) {
pending -= count;
while (count--) {
writel(xmit->buf[xmit->tail],
port->membase + ALTERA_JTAGUART_DATA_REG);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
}
if (pending < WAKEUP_CHARS)