Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6

This commit is contained in:
David S. Miller 2010-08-16 14:09:34 -07:00
commit 300a103d15
3413 changed files with 162402 additions and 388470 deletions

View file

@ -216,7 +216,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
unsigned long flags;
unsigned int baud, quot, h_lcr;
unsigned int baud, quot, h_lcr, b;
/*
* We don't support modem control lines.
@ -234,12 +234,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
*/
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
if (port->state && port->state->port.tty) {
struct tty_struct *tty = port->state->port.tty;
unsigned int b = port->uartclk / (16 * quot);
tty_encode_baud_rate(tty, b, b);
}
b = port->uartclk / (16 * quot);
tty_termios_encode_baud_rate(termios, b, b);
switch (termios->c_cflag & CSIZE) {
case CS5:

View file

@ -78,10 +78,6 @@ struct m68k_serial *m68k_consinfo = 0;
#define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */
#ifdef CONFIG_CONSOLE
extern wait_queue_head_t keypress_wait;
#endif
struct tty_driver *serial_driver;
/* number of characters left in xmit buffer before we ask for more */
@ -102,19 +98,13 @@ static void change_speed(struct m68k_serial *info);
* Setup for console. Argument comes from the boot command line.
*/
#if defined(CONFIG_M68EZ328ADS) || defined(CONFIG_ALMA_ANS) || defined(CONFIG_DRAGONIXVZ)
#define CONSOLE_BAUD_RATE 115200
#define DEFAULT_CBAUD B115200
#else
/* (es) */
/* note: this is messy, but it works, again, perhaps defined somewhere else?*/
#ifdef CONFIG_M68VZ328
#define CONSOLE_BAUD_RATE 19200
#define DEFAULT_CBAUD B19200
#endif
/* (/es) */
/* note: this is messy, but it works, again, perhaps defined somewhere else?*/
#ifdef CONFIG_M68VZ328
#define CONSOLE_BAUD_RATE 19200
#define DEFAULT_CBAUD B19200
#endif
#ifndef CONSOLE_BAUD_RATE
#define CONSOLE_BAUD_RATE 9600
#define DEFAULT_CBAUD B9600
@ -300,10 +290,6 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx)
return;
#endif /* CONFIG_MAGIC_SYSRQ */
}
/* It is a 'keyboard interrupt' ;-) */
#ifdef CONFIG_CONSOLE
wake_up(&keypress_wait);
#endif
}
if(!tty)
@ -1243,7 +1229,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
retval = -ERESTARTSYS;
break;
}
tty_unlock();
schedule();
tty_lock();
}
current->state = TASK_RUNNING;
remove_wait_queue(&info->open_wait, &wait);

View file

@ -1705,7 +1705,6 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
printk("jiff=%lu...", jiffies);
#endif
lock_kernel();
/* We go through the loop at least once because we can't tell
* exactly when the last character exits the shifter. There can
* be at least two characters waiting to be sent after the buffers
@ -1734,7 +1733,6 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
bdp--;
} while (bdp->status & BD_SC_READY);
current->state = TASK_RUNNING;
unlock_kernel();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
@ -1862,7 +1860,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
printk("block_til_ready blocking: ttys%d, count = %d\n",
info->line, state->count);
#endif
tty_unlock();
schedule();
tty_lock();
}
current->state = TASK_RUNNING;
remove_wait_queue(&info->open_wait, &wait);

View file

@ -241,7 +241,7 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 128,
.tx_loadsz = 128,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO,
.flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
},
[PORT_16654] = {
.name = "ST16654",
@ -300,6 +300,13 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
[PORT_U6_16550A] = {
.name = "U6_16550A",
.fifo_size = 64,
.tx_loadsz = 64,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
};
#if defined(CONFIG_MIPS_ALCHEMY)
@ -1070,6 +1077,15 @@ static void autoconfig_16550a(struct uart_8250_port *up)
DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
}
serial_outp(up, UART_IER, iersave);
/*
* We distinguish between 16550A and U6 16550A by counting
* how many bytes are in the FIFO.
*/
if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
up->port.type = PORT_U6_16550A;
up->capabilities |= UART_CAP_AFE;
}
}
/*
@ -2224,9 +2240,9 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int
return quot;
}
static void
serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
void
serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned char cval, fcr = 0;
@ -2402,16 +2418,22 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud);
}
EXPORT_SYMBOL(serial8250_do_set_termios);
static void
serial8250_set_ldisc(struct uart_port *port)
serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
int line = port->line;
if (port->set_termios)
port->set_termios(port, termios, old);
else
serial8250_do_set_termios(port, termios, old);
}
if (line >= port->state->port.tty->driver->num)
return;
if (port->state->port.tty->ldisc->ops->num == N_PPS) {
static void
serial8250_set_ldisc(struct uart_port *port, int new)
{
if (new == N_PPS) {
port->flags |= UPF_HARDPPS_CD;
serial8250_enable_ms(port);
} else
@ -2987,6 +3009,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
port.type = p->type;
port.serial_in = p->serial_in;
port.serial_out = p->serial_out;
port.set_termios = p->set_termios;
port.dev = &dev->dev;
port.irqflags |= irqflag;
ret = serial8250_register_port(&port);
@ -3150,6 +3173,9 @@ int serial8250_register_port(struct uart_port *port)
uart->port.serial_in = port->serial_in;
if (port->serial_out)
uart->port.serial_out = port->serial_out;
/* Possibly override set_termios call */
if (port->set_termios)
uart->port.set_termios = port->set_termios;
ret = uart_add_one_port(&serial8250_reg, &uart->port);
if (ret == 0)

View file

@ -19,9 +19,11 @@
* The user can specify the device directly, e.g.,
* earlycon=uart8250,io,0x3f8,9600n8
* earlycon=uart8250,mmio,0xff5e0000,115200n8
* earlycon=uart8250,mmio32,0xff5e0000,115200n8
* or
* console=uart8250,io,0x3f8,9600n8
* console=uart8250,mmio,0xff5e0000,115200n8
* console=uart8250,mmio32,0xff5e0000,115200n8
*/
#include <linux/tty.h>
@ -48,18 +50,31 @@ static struct early_serial8250_device early_device;
static unsigned int __init serial_in(struct uart_port *port, int offset)
{
if (port->iotype == UPIO_MEM)
switch (port->iotype) {
case UPIO_MEM:
return readb(port->membase + offset);
else
case UPIO_MEM32:
return readl(port->membase + (offset << 2));
case UPIO_PORT:
return inb(port->iobase + offset);
default:
return 0;
}
}
static void __init serial_out(struct uart_port *port, int offset, int value)
{
if (port->iotype == UPIO_MEM)
switch (port->iotype) {
case UPIO_MEM:
writeb(value, port->membase + offset);
else
break;
case UPIO_MEM32:
writel(value, port->membase + (offset << 2));
break;
case UPIO_PORT:
outb(value, port->iobase + offset);
break;
}
}
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
@ -137,15 +152,21 @@ static int __init parse_options(struct early_serial8250_device *device,
char *options)
{
struct uart_port *port = &device->port;
int mmio, length;
int mmio, mmio32, length;
if (!options)
return -ENODEV;
port->uartclk = BASE_BAUD * 16;
if (!strncmp(options, "mmio,", 5)) {
port->iotype = UPIO_MEM;
port->mapbase = simple_strtoul(options + 5, &options, 0);
mmio = !strncmp(options, "mmio,", 5);
mmio32 = !strncmp(options, "mmio32,", 7);
if (mmio || mmio32) {
port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
port->mapbase = simple_strtoul(options + (mmio ? 5 : 7),
&options, 0);
if (mmio32)
port->regshift = 2;
#ifdef CONFIG_FIX_EARLYCON_MEM
set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
port->mapbase & PAGE_MASK);
@ -157,11 +178,10 @@ static int __init parse_options(struct early_serial8250_device *device,
if (!port->membase) {
printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
__func__,
(unsigned long long)port->mapbase);
(unsigned long long) port->mapbase);
return -ENOMEM;
}
#endif
mmio = 1;
} else if (!strncmp(options, "io,", 3)) {
port->iotype = UPIO_PORT;
port->iobase = simple_strtoul(options + 3, &options, 0);
@ -181,11 +201,18 @@ static int __init parse_options(struct early_serial8250_device *device,
device->baud);
}
printk(KERN_INFO "Early serial console at %s 0x%llx (options '%s')\n",
mmio ? "MMIO" : "I/O port",
mmio ? (unsigned long long) port->mapbase
: (unsigned long long) port->iobase,
device->options);
if (mmio || mmio32)
printk(KERN_INFO
"Early serial console at MMIO%s 0x%llu (options '%s')\n",
mmio32 ? "32" : "",
(unsigned long long)port->mapbase,
device->options);
else
printk(KERN_INFO
"Early serial console at I/O port 0x%lu (options '%s')\n",
port->iobase,
device->options);
return 0;
}

View file

@ -994,6 +994,7 @@ static int skip_tx_en_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_TITAN_800E 0xA014
#define PCI_DEVICE_ID_TITAN_200EI 0xA016
#define PCI_DEVICE_ID_TITAN_200EISI 0xA017
#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@ -1542,6 +1543,8 @@ enum pci_board_num_t {
pbn_b2_4_921600,
pbn_b2_8_921600,
pbn_b2_8_1152000,
pbn_b2_bt_1_115200,
pbn_b2_bt_2_115200,
pbn_b2_bt_4_115200,
@ -1960,6 +1963,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.uart_offset = 8,
},
[pbn_b2_8_1152000] = {
.flags = FL_BASE2,
.num_ports = 8,
.base_baud = 1152000,
.uart_offset = 8,
},
[pbn_b2_bt_1_115200] = {
.flags = FL_BASE2|FL_BASE_BARS,
.num_ports = 1,
@ -2875,6 +2885,9 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_bt_2_921600 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958,
PCI_ANY_ID , PCI_ANY_ID, 0, 0,
pbn_b2_8_1152000 },
/*
* Oxford Semiconductor Inc. Tornado PCI express device range.

View file

@ -536,12 +536,13 @@ config SERIAL_S3C6400
config SERIAL_S5PV210
tristate "Samsung S5PV210 Serial port support"
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442)
select SERIAL_SAMSUNG_UARTS_4 if CPU_S5PV210
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_S5PV310)
select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_S5PV310)
default y
help
Serial port support for Samsung's S5P Family of SoC's
config SERIAL_MAX3100
tristate "MAX3100 support"
depends on SPI
@ -549,6 +550,22 @@ config SERIAL_MAX3100
help
MAX3100 chip support
config SERIAL_MAX3107
tristate "MAX3107 support"
depends on SPI
select SERIAL_CORE
help
MAX3107 chip support
config SERIAL_MAX3107_AAVA
tristate "MAX3107 AAVA platform support"
depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB
select SERIAL_CORE
help
Support for the MAX3107 chip configuration found on the AAVA
platform. Includes the extra initialisation and GPIO support
neded for this device.
config SERIAL_DZ
bool "DECstation DZ serial driver"
depends on MACH_DECSTATION && 32BIT
@ -690,6 +707,33 @@ config SERIAL_SA1100_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
config SERIAL_MRST_MAX3110
tristate "SPI UART driver for Max3110"
depends on SPI_DW_PCI
select SERIAL_CORE
select SERIAL_CORE_CONSOLE
help
This is the UART protocol driver for the MAX3110 device on
the Intel Moorestown platform. On other systems use the max3100
driver.
config MRST_MAX3110_IRQ
boolean "Enable GPIO IRQ for Max3110 over Moorestown"
default n
depends on SERIAL_MRST_MAX3110 && GPIO_LANGWELL
help
This has to be enabled after Moorestown GPIO driver is loaded
config SERIAL_MFD_HSU
tristate "Medfield High Speed UART support"
depends on PCI
select SERIAL_CORE
config SERIAL_MFD_HSU_CONSOLE
boolean "Medfile HSU serial console support"
depends on SERIAL_MFD_HSU=y
select SERIAL_CORE_CONSOLE
config SERIAL_BFIN
tristate "Blackfin serial port support"
depends on BLACKFIN

View file

@ -46,6 +46,8 @@ obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_MAX3107) += max3107.o
obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
obj-$(CONFIG_SERIAL_MUX) += mux.o
obj-$(CONFIG_SERIAL_68328) += 68328serial.o
@ -84,3 +86,5 @@ 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
obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o
obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o

View file

@ -394,7 +394,7 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
static void altera_uart_console_putc(struct uart_port *port, const char c)
{
while (!(readl(port->membase + ALTERA_UART_STATUS_REG) &
ALTERA_UART_STATUS_TRDY_MSK))
ALTERA_UART_STATUS_TRDY_MSK))
cpu_relax();
writel(c, port->membase + ALTERA_UART_TXDATA_REG);

View file

@ -551,7 +551,7 @@ static struct uart_driver grlib_apbuart_driver = {
/* OF Platform Driver */
/* ======================================================================== */
static int __devinit apbuart_probe(struct of_device *op,
static int __devinit apbuart_probe(struct platform_device *op,
const struct of_device_id *match)
{
int i = -1;

View file

@ -217,7 +217,8 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
if (rs485conf->flags & SER_RS485_ENABLED) {
dev_dbg(port->dev, "Setting UART to RS485\n");
atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
UART_PUT_TTGR(port, rs485conf->delay_rts_before_send);
if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
UART_PUT_TTGR(port, rs485conf->delay_rts_after_send);
mode |= ATMEL_US_USMODE_RS485;
} else {
dev_dbg(port->dev, "Setting UART to RS232\n");
@ -292,7 +293,9 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
dev_dbg(port->dev, "Setting UART to RS485\n");
UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
UART_PUT_TTGR(port,
atmel_port->rs485.delay_rts_after_send);
mode |= ATMEL_US_USMODE_RS485;
} else {
dev_dbg(port->dev, "Setting UART to RS232\n");
@ -1211,7 +1214,9 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
dev_dbg(port->dev, "Setting UART to RS485\n");
UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
UART_PUT_TTGR(port,
atmel_port->rs485.delay_rts_after_send);
mode |= ATMEL_US_USMODE_RS485;
} else {
dev_dbg(port->dev, "Setting UART to RS232\n");

View file

@ -957,15 +957,12 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
* Enable the IrDA function if tty->ldisc.num is N_IRDA.
* In other cases, disable IrDA function.
*/
static void bfin_serial_set_ldisc(struct uart_port *port)
static void bfin_serial_set_ldisc(struct uart_port *port, int ld)
{
int line = port->line;
unsigned short val;
if (line >= port->state->port.tty->driver->num)
return;
switch (port->state->port.tty->termios->c_line) {
switch (ld) {
case N_IRDA:
val = UART_GET_GCTL(&bfin_serial_ports[line]);
val |= (IREN | RPOLC);

View file

@ -1340,7 +1340,7 @@ static struct uart_driver cpm_reg = {
static int probe_index;
static int __devinit cpm_uart_probe(struct of_device *ofdev,
static int __devinit cpm_uart_probe(struct platform_device *ofdev,
const struct of_device_id *match)
{
int index = probe_index++;
@ -1364,7 +1364,7 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev,
return uart_add_one_port(&cpm_reg, &pinfo->port);
}
static int __devexit cpm_uart_remove(struct of_device *ofdev)
static int __devexit cpm_uart_remove(struct platform_device *ofdev)
{
struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev);
return uart_remove_one_port(&cpm_reg, &pinfo->port);

View file

@ -3724,6 +3724,17 @@ rs_ioctl(struct tty_struct *tty, struct file * file,
return e100_enable_rs485(tty, &rs485data);
}
case TIOCGRS485:
{
struct serial_rs485 *rs485data =
&(((struct e100_serial *)tty->driver_data)->rs485);
/* This is the ioctl to get RS485 data from user-space */
if (copy_to_user((struct serial_rs485 *) arg,
rs485data,
sizeof(serial_rs485)))
return -EFAULT;
break;
}
case TIOCSERWRRS485:
{
@ -3924,7 +3935,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
* Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO
* R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k)
*/
lock_kernel();
orig_jiffies = jiffies;
while (info->xmit.head != info->xmit.tail || /* More in send queue */
(*info->ostatusadr & 0x007f) || /* more in FIFO */
@ -3941,7 +3951,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
curr_time_usec - info->last_tx_active_usec;
}
set_current_state(TASK_RUNNING);
unlock_kernel();
}
/*
@ -3981,7 +3990,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
wait_event_interruptible(info->close_wait,
wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART
if (info->flags & ASYNC_HUP_NOTIFY)
@ -4057,7 +4066,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
printk("block_til_ready blocking: ttyS%d, count = %d\n",
info->line, info->count);
#endif
tty_unlock();
schedule();
tty_lock();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
@ -4139,7 +4150,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
wait_event_interruptible(info->close_wait,
wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART
return ((info->flags & ASYNC_HUP_NOTIFY) ?
@ -4522,8 +4533,8 @@ static int __init rs_init(void)
INIT_WORK(&info->work, do_softint);
if (info->enabled) {
printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
serial_driver->name, info->line, (unsigned int)info->ioport);
printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n",
serial_driver->name, info->line, info->ioport);
}
}
#ifdef CONFIG_ETRAX_FAST_TIMER

View file

@ -909,13 +909,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
rational_best_approximation(16 * div * baud, sport->port.uartclk,
1 << 16, 1 << 16, &num, &denom);
if (port->state && port->state->port.tty) {
tdiv64 = sport->port.uartclk;
tdiv64 *= num;
do_div(tdiv64, denom * 16 * div);
tty_encode_baud_rate(sport->port.state->port.tty,
tdiv64 = sport->port.uartclk;
tdiv64 *= num;
do_div(tdiv64, denom * 16 * div);
tty_termios_encode_baud_rate(termios,
(speed_t)tdiv64, (speed_t)tdiv64);
}
num -= 1;
denom -= 1;

View file

@ -954,12 +954,13 @@ ioc3_change_speed(struct uart_port *the_port,
struct ktermios *new_termios, struct ktermios *old_termios)
{
struct ioc3_port *port = get_ioc3_port(the_port);
unsigned int cflag;
unsigned int cflag, iflag;
int baud;
int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
struct uart_state *state = the_port->state;
cflag = new_termios->c_cflag;
iflag = new_termios->c_iflag;
switch (cflag & CSIZE) {
case CS5:
@ -1000,12 +1001,12 @@ ioc3_change_speed(struct uart_port *the_port,
state->port.tty->low_latency = 1;
if (I_IGNPAR(state->port.tty))
if (iflag & IGNPAR)
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
if (I_IGNBRK(state->port.tty)) {
if (iflag & IGNBRK) {
the_port->ignore_status_mask &= ~N_BREAK;
if (I_IGNPAR(state->port.tty))
if (iflag & IGNPAR)
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
}
if (!(cflag & CREAD)) {

View file

@ -1685,11 +1685,12 @@ ioc4_change_speed(struct uart_port *the_port,
{
struct ioc4_port *port = get_ioc4_port(the_port, 0);
int baud, bits;
unsigned cflag;
unsigned cflag, iflag;
int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
struct uart_state *state = the_port->state;
cflag = new_termios->c_cflag;
iflag = new_termios->c_iflag;
switch (cflag & CSIZE) {
case CS5:
@ -1741,12 +1742,12 @@ ioc4_change_speed(struct uart_port *the_port,
state->port.tty->low_latency = 1;
if (I_IGNPAR(state->port.tty))
if (iflag & IGNPAR)
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
if (I_IGNBRK(state->port.tty)) {
if (iflag & IGNBRK) {
the_port->ignore_status_mask &= ~N_BREAK;
if (I_IGNPAR(state->port.tty))
if (iflag & IGNPAR)
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
}
if (!(cflag & CREAD)) {

View file

@ -430,17 +430,14 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
int baud = 0;
unsigned cflag;
u32 param_new, param_mask, parity = 0;
struct tty_struct *tty = s->port.state->port.tty;
dev_dbg(&s->spi->dev, "%s\n", __func__);
if (!tty)
return;
cflag = termios->c_cflag;
param_new = 0;
param_mask = 0;
baud = tty_get_baud_rate(tty);
baud = tty_termios_baud_rate(termios);
param_new = s->conf & MAX3100_BAUD;
switch (baud) {
case 300:
@ -485,7 +482,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
default:
baud = s->baud;
}
tty_encode_baud_rate(tty, baud, baud);
tty_termios_encode_baud_rate(termios, baud, baud);
s->baud = baud;
param_mask |= MAX3100_BAUD;

View file

@ -0,0 +1,344 @@
/*
* max3107.c - spi uart protocol driver for Maxim 3107
* Based on max3100.c
* by Christian Pellegrin <chripell@evolware.org>
* and max3110.c
* by Feng Tang <feng.tang@intel.com>
*
* Copyright (C) Aavamobile 2009
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/spi/spi.h>
#include <linux/freezer.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/sfi.h>
#include <asm/mrst.h>
#include "max3107.h"
/* GPIO direction to input function */
static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
u16 buf[1]; /* Buffer for SPI transfer */
if (offset >= MAX3107_GPIO_COUNT) {
dev_err(&s->spi->dev, "Invalid GPIO\n");
return -EINVAL;
}
/* Read current GPIO configuration register */
buf[0] = MAX3107_GPIOCFG_REG;
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n");
return -EIO;
}
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
/* Set GPIO to input */
buf[0] &= ~(0x0001 << offset);
/* Write new GPIO configuration register value */
buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG);
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, NULL, 2)) {
dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n");
return -EIO;
}
return 0;
}
/* GPIO direction to output function */
static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset,
int value)
{
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
u16 buf[2]; /* Buffer for SPI transfers */
if (offset >= MAX3107_GPIO_COUNT) {
dev_err(&s->spi->dev, "Invalid GPIO\n");
return -EINVAL;
}
/* Read current GPIO configuration and data registers */
buf[0] = MAX3107_GPIOCFG_REG;
buf[1] = MAX3107_GPIODATA_REG;
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) {
dev_err(&s->spi->dev, "SPI transfer gpio failed\n");
return -EIO;
}
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
buf[1] &= MAX3107_SPI_RX_DATA_MASK;
/* Set GPIO to output */
buf[0] |= (0x0001 << offset);
/* Set value */
if (value)
buf[1] |= (0x0001 << offset);
else
buf[1] &= ~(0x0001 << offset);
/* Write new GPIO configuration and data register values */
buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG);
buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG);
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, NULL, 4)) {
dev_err(&s->spi->dev,
"SPI transfer for GPIO conf data w failed\n");
return -EIO;
}
return 0;
}
/* GPIO value query function */
static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
u16 buf[1]; /* Buffer for SPI transfer */
if (offset >= MAX3107_GPIO_COUNT) {
dev_err(&s->spi->dev, "Invalid GPIO\n");
return -EINVAL;
}
/* Read current GPIO data register */
buf[0] = MAX3107_GPIODATA_REG;
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n");
return -EIO;
}
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
/* Return value */
return buf[0] & (0x0001 << offset);
}
/* GPIO value set function */
static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
u16 buf[2]; /* Buffer for SPI transfers */
if (offset >= MAX3107_GPIO_COUNT) {
dev_err(&s->spi->dev, "Invalid GPIO\n");
return;
}
/* Read current GPIO configuration registers*/
buf[0] = MAX3107_GPIODATA_REG;
buf[1] = MAX3107_GPIOCFG_REG;
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) {
dev_err(&s->spi->dev,
"SPI transfer for GPIO data and config read failed\n");
return;
}
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
buf[1] &= MAX3107_SPI_RX_DATA_MASK;
if (!(buf[1] & (0x0001 << offset))) {
/* Configured as input, can't set value */
dev_warn(&s->spi->dev,
"Trying to set value for input GPIO\n");
return;
}
/* Set value */
if (value)
buf[0] |= (0x0001 << offset);
else
buf[0] &= ~(0x0001 << offset);
/* Write new GPIO data register value */
buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG);
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, NULL, 2))
dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n");
}
/* GPIO chip data */
static struct gpio_chip max3107_gpio_chip = {
.owner = THIS_MODULE,
.direction_input = max3107_gpio_direction_in,
.direction_output = max3107_gpio_direction_out,
.get = max3107_gpio_get,
.set = max3107_gpio_set,
.can_sleep = 1,
.base = MAX3107_GPIO_BASE,
.ngpio = MAX3107_GPIO_COUNT,
};
/**
* max3107_aava_reset - reset on AAVA systems
* @spi: The SPI device we are probing
*
* Reset the device ready for probing.
*/
static int max3107_aava_reset(struct spi_device *spi)
{
/* Reset the chip */
if (gpio_request(MAX3107_RESET_GPIO, "max3107")) {
pr_err("Requesting RESET GPIO failed\n");
return -EIO;
}
if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) {
pr_err("Setting RESET GPIO to 0 failed\n");
gpio_free(MAX3107_RESET_GPIO);
return -EIO;
}
msleep(MAX3107_RESET_DELAY);
if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) {
pr_err("Setting RESET GPIO to 1 failed\n");
gpio_free(MAX3107_RESET_GPIO);
return -EIO;
}
gpio_free(MAX3107_RESET_GPIO);
msleep(MAX3107_WAKEUP_DELAY);
return 0;
}
static int max3107_aava_configure(struct max3107_port *s)
{
int retval;
/* Initialize GPIO chip data */
s->chip = max3107_gpio_chip;
s->chip.label = s->spi->modalias;
s->chip.dev = &s->spi->dev;
/* Add GPIO chip */
retval = gpiochip_add(&s->chip);
if (retval) {
dev_err(&s->spi->dev, "Adding GPIO chip failed\n");
return retval;
}
/* Temporary fix for EV2 boot problems, set modem reset to 0 */
max3107_gpio_direction_out(&s->chip, 3, 0);
return 0;
}
#if 0
/* This will get enabled once we have the board stuff merged for this
specific case */
static const struct baud_table brg13_ext[] = {
{ 300, MAX3107_BRG13_B300 },
{ 600, MAX3107_BRG13_B600 },
{ 1200, MAX3107_BRG13_B1200 },
{ 2400, MAX3107_BRG13_B2400 },
{ 4800, MAX3107_BRG13_B4800 },
{ 9600, MAX3107_BRG13_B9600 },
{ 19200, MAX3107_BRG13_B19200 },
{ 57600, MAX3107_BRG13_B57600 },
{ 115200, MAX3107_BRG13_B115200 },
{ 230400, MAX3107_BRG13_B230400 },
{ 460800, MAX3107_BRG13_B460800 },
{ 921600, MAX3107_BRG13_B921600 },
{ 0, 0 }
};
static void max3107_aava_init(struct max3107_port *s)
{
/*override for AAVA SC specific*/
if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) {
if (get_koski_build_id() <= KOSKI_EV2)
if (s->ext_clk) {
s->brg_cfg = MAX3107_BRG13_B9600;
s->baud_tbl = (struct baud_table *)brg13_ext;
}
}
}
#endif
static int __devexit max3107_aava_remove(struct spi_device *spi)
{
struct max3107_port *s = dev_get_drvdata(&spi->dev);
/* Remove GPIO chip */
if (gpiochip_remove(&s->chip))
dev_warn(&spi->dev, "Removing GPIO chip failed\n");
/* Then do the default remove */
return max3107_remove(spi);
}
/* Platform data */
static struct max3107_plat aava_plat_data = {
.loopback = 0,
.ext_clk = 1,
/* .init = max3107_aava_init, */
.configure = max3107_aava_configure,
.hw_suspend = max3107_hw_susp,
.polled_mode = 0,
.poll_time = 0,
};
static int __devinit max3107_probe_aava(struct spi_device *spi)
{
int err = max3107_aava_reset(spi);
if (err < 0)
return err;
return max3107_probe(spi, &aava_plat_data);
}
/* Spi driver data */
static struct spi_driver max3107_driver = {
.driver = {
.name = "aava-max3107",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = max3107_probe_aava,
.remove = __devexit_p(max3107_aava_remove),
.suspend = max3107_suspend,
.resume = max3107_resume,
};
/* Driver init function */
static int __init max3107_init(void)
{
return spi_register_driver(&max3107_driver);
}
/* Driver exit function */
static void __exit max3107_exit(void)
{
spi_unregister_driver(&max3107_driver);
}
module_init(max3107_init);
module_exit(max3107_exit);
MODULE_DESCRIPTION("MAX3107 driver");
MODULE_AUTHOR("Aavamobile");
MODULE_ALIAS("aava-max3107-spi");
MODULE_LICENSE("GPL v2");

1197
drivers/serial/max3107.c Normal file

File diff suppressed because it is too large Load diff

441
drivers/serial/max3107.h Normal file
View file

@ -0,0 +1,441 @@
/*
* max3107.h - spi uart protocol driver header for Maxim 3107
*
* Copyright (C) Aavamobile 2009
* Based on serial_max3100.h by Christian Pellegrin
*
* 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 _MAX3107_H
#define _MAX3107_H
/* Serial error status definitions */
#define MAX3107_PARITY_ERROR 1
#define MAX3107_FRAME_ERROR 2
#define MAX3107_OVERRUN_ERROR 4
#define MAX3107_ALL_ERRORS (MAX3107_PARITY_ERROR | \
MAX3107_FRAME_ERROR | \
MAX3107_OVERRUN_ERROR)
/* GPIO definitions */
#define MAX3107_GPIO_BASE 88
#define MAX3107_GPIO_COUNT 4
/* GPIO connected to chip's reset pin */
#define MAX3107_RESET_GPIO 87
/* Chip reset delay */
#define MAX3107_RESET_DELAY 10
/* Chip wakeup delay */
#define MAX3107_WAKEUP_DELAY 50
/* Sleep mode definitions */
#define MAX3107_DISABLE_FORCED_SLEEP 0
#define MAX3107_ENABLE_FORCED_SLEEP 1
#define MAX3107_DISABLE_AUTOSLEEP 2
#define MAX3107_ENABLE_AUTOSLEEP 3
/* Definitions for register access with SPI transfers
*
* SPI transfer format:
*
* Master to slave bits xzzzzzzzyyyyyyyy
* Slave to master bits aaaaaaaabbbbbbbb
*
* where:
* x = 0 for reads, 1 for writes
* z = register address
* y = new register value if write, 0 if read
* a = unspecified
* b = register value if read, unspecified if write
*/
/* SPI speed */
#define MAX3107_SPI_SPEED (3125000 * 2)
/* Write bit */
#define MAX3107_WRITE_BIT (1 << 15)
/* SPI TX data mask */
#define MAX3107_SPI_RX_DATA_MASK (0x00ff)
/* SPI RX data mask */
#define MAX3107_SPI_TX_DATA_MASK (0x00ff)
/* Register access masks */
#define MAX3107_RHR_REG (0x0000) /* RX FIFO */
#define MAX3107_THR_REG (0x0000) /* TX FIFO */
#define MAX3107_IRQEN_REG (0x0100) /* IRQ enable */
#define MAX3107_IRQSTS_REG (0x0200) /* IRQ status */
#define MAX3107_LSR_IRQEN_REG (0x0300) /* LSR IRQ enable */
#define MAX3107_LSR_IRQSTS_REG (0x0400) /* LSR IRQ status */
#define MAX3107_SPCHR_IRQEN_REG (0x0500) /* Special char IRQ enable */
#define MAX3107_SPCHR_IRQSTS_REG (0x0600) /* Special char IRQ status */
#define MAX3107_STS_IRQEN_REG (0x0700) /* Status IRQ enable */
#define MAX3107_STS_IRQSTS_REG (0x0800) /* Status IRQ status */
#define MAX3107_MODE1_REG (0x0900) /* MODE1 */
#define MAX3107_MODE2_REG (0x0a00) /* MODE2 */
#define MAX3107_LCR_REG (0x0b00) /* LCR */
#define MAX3107_RXTO_REG (0x0c00) /* RX timeout */
#define MAX3107_HDPIXDELAY_REG (0x0d00) /* Auto transceiver delays */
#define MAX3107_IRDA_REG (0x0e00) /* IRDA settings */
#define MAX3107_FLOWLVL_REG (0x0f00) /* Flow control levels */
#define MAX3107_FIFOTRIGLVL_REG (0x1000) /* FIFO IRQ trigger levels */
#define MAX3107_TXFIFOLVL_REG (0x1100) /* TX FIFO level */
#define MAX3107_RXFIFOLVL_REG (0x1200) /* RX FIFO level */
#define MAX3107_FLOWCTRL_REG (0x1300) /* Flow control */
#define MAX3107_XON1_REG (0x1400) /* XON1 character */
#define MAX3107_XON2_REG (0x1500) /* XON2 character */
#define MAX3107_XOFF1_REG (0x1600) /* XOFF1 character */
#define MAX3107_XOFF2_REG (0x1700) /* XOFF2 character */
#define MAX3107_GPIOCFG_REG (0x1800) /* GPIO config */
#define MAX3107_GPIODATA_REG (0x1900) /* GPIO data */
#define MAX3107_PLLCFG_REG (0x1a00) /* PLL config */
#define MAX3107_BRGCFG_REG (0x1b00) /* Baud rate generator conf */
#define MAX3107_BRGDIVLSB_REG (0x1c00) /* Baud rate divisor LSB */
#define MAX3107_BRGDIVMSB_REG (0x1d00) /* Baud rate divisor MSB */
#define MAX3107_CLKSRC_REG (0x1e00) /* Clock source */
#define MAX3107_REVID_REG (0x1f00) /* Revision identification */
/* IRQ register bits */
#define MAX3107_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */
#define MAX3107_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */
#define MAX3107_IRQ_STS_BIT (1 << 2) /* Status interrupt */
#define MAX3107_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */
#define MAX3107_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */
#define MAX3107_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */
#define MAX3107_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */
#define MAX3107_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */
/* LSR register bits */
#define MAX3107_LSR_RXTO_BIT (1 << 0) /* RX timeout */
#define MAX3107_LSR_RXOVR_BIT (1 << 1) /* RX overrun */
#define MAX3107_LSR_RXPAR_BIT (1 << 2) /* RX parity error */
#define MAX3107_LSR_FRERR_BIT (1 << 3) /* Frame error */
#define MAX3107_LSR_RXBRK_BIT (1 << 4) /* RX break */
#define MAX3107_LSR_RXNOISE_BIT (1 << 5) /* RX noise */
#define MAX3107_LSR_UNDEF6_BIT (1 << 6) /* Undefined/not used */
#define MAX3107_LSR_CTS_BIT (1 << 7) /* CTS pin state */
/* Special character register bits */
#define MAX3107_SPCHR_XON1_BIT (1 << 0) /* XON1 character */
#define MAX3107_SPCHR_XON2_BIT (1 << 1) /* XON2 character */
#define MAX3107_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */
#define MAX3107_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */
#define MAX3107_SPCHR_BREAK_BIT (1 << 4) /* RX break */
#define MAX3107_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */
#define MAX3107_SPCHR_UNDEF6_BIT (1 << 6) /* Undefined/not used */
#define MAX3107_SPCHR_UNDEF7_BIT (1 << 7) /* Undefined/not used */
/* Status register bits */
#define MAX3107_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */
#define MAX3107_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */
#define MAX3107_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */
#define MAX3107_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */
#define MAX3107_STS_UNDEF4_BIT (1 << 4) /* Undefined/not used */
#define MAX3107_STS_CLKREADY_BIT (1 << 5) /* Clock ready */
#define MAX3107_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */
#define MAX3107_STS_UNDEF7_BIT (1 << 7) /* Undefined/not used */
/* MODE1 register bits */
#define MAX3107_MODE1_RXDIS_BIT (1 << 0) /* RX disable */
#define MAX3107_MODE1_TXDIS_BIT (1 << 1) /* TX disable */
#define MAX3107_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */
#define MAX3107_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */
#define MAX3107_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */
#define MAX3107_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */
#define MAX3107_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */
#define MAX3107_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */
/* MODE2 register bits */
#define MAX3107_MODE2_RST_BIT (1 << 0) /* Chip reset */
#define MAX3107_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */
#define MAX3107_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */
#define MAX3107_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */
#define MAX3107_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */
#define MAX3107_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */
#define MAX3107_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */
#define MAX3107_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */
/* LCR register bits */
#define MAX3107_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */
#define MAX3107_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1
*
* Word length bits table:
* 00 -> 5 bit words
* 01 -> 6 bit words
* 10 -> 7 bit words
* 11 -> 8 bit words
*/
#define MAX3107_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit
*
* STOP length bit table:
* 0 -> 1 stop bit
* 1 -> 1-1.5 stop bits if
* word length is 5,
* 2 stop bits otherwise
*/
#define MAX3107_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */
#define MAX3107_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */
#define MAX3107_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */
#define MAX3107_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */
#define MAX3107_LCR_RTS_BIT (1 << 7) /* RTS pin control */
#define MAX3107_LCR_WORD_LEN_5 (0x0000)
#define MAX3107_LCR_WORD_LEN_6 (0x0001)
#define MAX3107_LCR_WORD_LEN_7 (0x0002)
#define MAX3107_LCR_WORD_LEN_8 (0x0003)
/* IRDA register bits */
#define MAX3107_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */
#define MAX3107_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */
#define MAX3107_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */
#define MAX3107_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */
#define MAX3107_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */
#define MAX3107_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */
#define MAX3107_IRDA_UNDEF6_BIT (1 << 6) /* Undefined/not used */
#define MAX3107_IRDA_UNDEF7_BIT (1 << 7) /* Undefined/not used */
/* Flow control trigger level register masks */
#define MAX3107_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */
#define MAX3107_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */
#define MAX3107_FLOWLVL_HALT(words) ((words/8) & 0x000f)
#define MAX3107_FLOWLVL_RES(words) (((words/8) & 0x000f) << 4)
/* FIFO interrupt trigger level register masks */
#define MAX3107_FIFOTRIGLVL_TX_MASK (0x000f) /* TX FIFO trigger level */
#define MAX3107_FIFOTRIGLVL_RX_MASK (0x00f0) /* RX FIFO trigger level */
#define MAX3107_FIFOTRIGLVL_TX(words) ((words/8) & 0x000f)
#define MAX3107_FIFOTRIGLVL_RX(words) (((words/8) & 0x000f) << 4)
/* Flow control register bits */
#define MAX3107_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */
#define MAX3107_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */
#define MAX3107_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs
* are used in conjunction with
* XOFF2 for definition of
* special character */
#define MAX3107_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */
#define MAX3107_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */
#define MAX3107_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1
*
* SWFLOW bits 1 & 0 table:
* 00 -> no transmitter flow
* control
* 01 -> receiver compares
* XON2 and XOFF2
* and controls
* transmitter
* 10 -> receiver compares
* XON1 and XOFF1
* and controls
* transmitter
* 11 -> receiver compares
* XON1, XON2, XOFF1 and
* XOFF2 and controls
* transmitter
*/
#define MAX3107_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */
#define MAX3107_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3
*
* SWFLOW bits 3 & 2 table:
* 00 -> no received flow
* control
* 01 -> transmitter generates
* XON2 and XOFF2
* 10 -> transmitter generates
* XON1 and XOFF1
* 11 -> transmitter generates
* XON1, XON2, XOFF1 and
* XOFF2
*/
/* GPIO configuration register bits */
#define MAX3107_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */
#define MAX3107_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */
#define MAX3107_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */
#define MAX3107_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */
#define MAX3107_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */
#define MAX3107_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */
#define MAX3107_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */
#define MAX3107_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */
/* GPIO DATA register bits */
#define MAX3107_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */
#define MAX3107_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */
#define MAX3107_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */
#define MAX3107_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */
#define MAX3107_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */
#define MAX3107_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */
#define MAX3107_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */
#define MAX3107_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */
/* PLL configuration register masks */
#define MAX3107_PLLCFG_PREDIV_MASK (0x003f) /* PLL predivision value */
#define MAX3107_PLLCFG_PLLFACTOR_MASK (0x00c0) /* PLL multiplication factor */
/* Baud rate generator configuration register masks and bits */
#define MAX3107_BRGCFG_FRACT_MASK (0x000f) /* Fractional portion of
* Baud rate generator divisor
*/
#define MAX3107_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */
#define MAX3107_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */
#define MAX3107_BRGCFG_UNDEF6_BIT (1 << 6) /* Undefined/not used */
#define MAX3107_BRGCFG_UNDEF7_BIT (1 << 7) /* Undefined/not used */
/* Clock source register bits */
#define MAX3107_CLKSRC_INTOSC_BIT (1 << 0) /* Internal osc enable */
#define MAX3107_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */
#define MAX3107_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */
#define MAX3107_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */
#define MAX3107_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */
#define MAX3107_CLKSRC_UNDEF5_BIT (1 << 5) /* Undefined/not used */
#define MAX3107_CLKSRC_UNDEF6_BIT (1 << 6) /* Undefined/not used */
#define MAX3107_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */
/* HW definitions */
#define MAX3107_RX_FIFO_SIZE 128
#define MAX3107_TX_FIFO_SIZE 128
#define MAX3107_REVID1 0x00a0
#define MAX3107_REVID2 0x00a1
/* Baud rate generator configuration values for external clock 13MHz */
#define MAX3107_BRG13_B300 (0x0A9400 | 0x05)
#define MAX3107_BRG13_B600 (0x054A00 | 0x03)
#define MAX3107_BRG13_B1200 (0x02A500 | 0x01)
#define MAX3107_BRG13_B2400 (0x015200 | 0x09)
#define MAX3107_BRG13_B4800 (0x00A900 | 0x04)
#define MAX3107_BRG13_B9600 (0x005400 | 0x0A)
#define MAX3107_BRG13_B19200 (0x002A00 | 0x05)
#define MAX3107_BRG13_B38400 (0x001500 | 0x03)
#define MAX3107_BRG13_B57600 (0x000E00 | 0x02)
#define MAX3107_BRG13_B115200 (0x000700 | 0x01)
#define MAX3107_BRG13_B230400 (0x000300 | 0x08)
#define MAX3107_BRG13_B460800 (0x000100 | 0x0c)
#define MAX3107_BRG13_B921600 (0x000100 | 0x1c)
/* Baud rate generator configuration values for external clock 26MHz */
#define MAX3107_BRG26_B300 (0x152800 | 0x0A)
#define MAX3107_BRG26_B600 (0x0A9400 | 0x05)
#define MAX3107_BRG26_B1200 (0x054A00 | 0x03)
#define MAX3107_BRG26_B2400 (0x02A500 | 0x01)
#define MAX3107_BRG26_B4800 (0x015200 | 0x09)
#define MAX3107_BRG26_B9600 (0x00A900 | 0x04)
#define MAX3107_BRG26_B19200 (0x005400 | 0x0A)
#define MAX3107_BRG26_B38400 (0x002A00 | 0x05)
#define MAX3107_BRG26_B57600 (0x001C00 | 0x03)
#define MAX3107_BRG26_B115200 (0x000E00 | 0x02)
#define MAX3107_BRG26_B230400 (0x000700 | 0x01)
#define MAX3107_BRG26_B460800 (0x000300 | 0x08)
#define MAX3107_BRG26_B921600 (0x000100 | 0x0C)
/* Baud rate generator configuration values for internal clock */
#define MAX3107_BRG13_IB300 (0x008000 | 0x00)
#define MAX3107_BRG13_IB600 (0x004000 | 0x00)
#define MAX3107_BRG13_IB1200 (0x002000 | 0x00)
#define MAX3107_BRG13_IB2400 (0x001000 | 0x00)
#define MAX3107_BRG13_IB4800 (0x000800 | 0x00)
#define MAX3107_BRG13_IB9600 (0x000400 | 0x00)
#define MAX3107_BRG13_IB19200 (0x000200 | 0x00)
#define MAX3107_BRG13_IB38400 (0x000100 | 0x00)
#define MAX3107_BRG13_IB57600 (0x000000 | 0x0B)
#define MAX3107_BRG13_IB115200 (0x000000 | 0x05)
#define MAX3107_BRG13_IB230400 (0x000000 | 0x03)
#define MAX3107_BRG13_IB460800 (0x000000 | 0x00)
#define MAX3107_BRG13_IB921600 (0x000000 | 0x00)
struct baud_table {
int baud;
u32 new_brg;
};
struct max3107_port {
/* UART port structure */
struct uart_port port;
/* SPI device structure */
struct spi_device *spi;
#if defined(CONFIG_GPIOLIB)
/* GPIO chip stucture */
struct gpio_chip chip;
#endif
/* Workqueue that does all the magic */
struct workqueue_struct *workqueue;
struct work_struct work;
/* Lock for shared data */
spinlock_t data_lock;
/* Device configuration */
int ext_clk; /* 1 if external clock used */
int loopback; /* Current loopback mode state */
int baud; /* Current baud rate */
/* State flags */
int suspended; /* Indicates suspend mode */
int tx_fifo_empty; /* Flag for TX FIFO state */
int rx_enabled; /* Flag for receiver state */
int tx_enabled; /* Flag for transmitter state */
u16 irqen_reg; /* Current IRQ enable register value */
/* Shared data */
u16 mode1_reg; /* Current mode1 register value*/
int mode1_commit; /* Flag for setting new mode1 register value */
u16 lcr_reg; /* Current LCR register value */
int lcr_commit; /* Flag for setting new LCR register value */
u32 brg_cfg; /* Current Baud rate generator config */
int brg_commit; /* Flag for setting new baud rate generator
* config
*/
struct baud_table *baud_tbl;
int handle_irq; /* Indicates that IRQ should be handled */
/* Rx buffer and str*/
u16 *rxbuf;
u8 *rxstr;
/* Tx buffer*/
u16 *txbuf;
struct max3107_plat *pdata; /* Platform data */
};
/* Platform data structure */
struct max3107_plat {
/* Loopback mode enable */
int loopback;
/* External clock enable */
int ext_clk;
/* Called during the register initialisation */
void (*init)(struct max3107_port *s);
/* Called when the port is found and configured */
int (*configure)(struct max3107_port *s);
/* HW suspend function */
void (*hw_suspend) (struct max3107_port *s, int suspend);
/* Polling mode enable */
int polled_mode;
/* Polling period if polling mode enabled */
int poll_time;
};
extern int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len);
extern void max3107_hw_susp(struct max3107_port *s, int suspend);
extern int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata);
extern int max3107_remove(struct spi_device *spi);
extern int max3107_suspend(struct spi_device *spi, pm_message_t state);
extern int max3107_resume(struct spi_device *spi);
#endif /* _LINUX_SERIAL_MAX3107_H */

View file

@ -70,16 +70,14 @@ static unsigned int mcf_tx_empty(struct uart_port *port)
static unsigned int mcf_get_mctrl(struct uart_port *port)
{
struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
unsigned long flags;
unsigned int sigs;
spin_lock_irqsave(&port->lock, flags);
sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ?
0 : TIOCM_CTS;
sigs |= (pp->sigs & TIOCM_RTS);
sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0);
sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0);
spin_unlock_irqrestore(&port->lock, flags);
return sigs;
}
@ -88,16 +86,13 @@ static unsigned int mcf_get_mctrl(struct uart_port *port)
static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
{
struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
pp->sigs = sigs;
mcf_setppdtr(port->line, (sigs & TIOCM_DTR));
if (sigs & TIOCM_RTS)
writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1);
else
writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0);
spin_unlock_irqrestore(&port->lock, flags);
}
/****************************************************************************/
@ -105,12 +100,9 @@ static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
static void mcf_start_tx(struct uart_port *port)
{
struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
pp->imr |= MCFUART_UIR_TXREADY;
writeb(pp->imr, port->membase + MCFUART_UIMR);
spin_unlock_irqrestore(&port->lock, flags);
}
/****************************************************************************/
@ -118,12 +110,9 @@ static void mcf_start_tx(struct uart_port *port)
static void mcf_stop_tx(struct uart_port *port)
{
struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
pp->imr &= ~MCFUART_UIR_TXREADY;
writeb(pp->imr, port->membase + MCFUART_UIMR);
spin_unlock_irqrestore(&port->lock, flags);
}
/****************************************************************************/
@ -131,12 +120,9 @@ static void mcf_stop_tx(struct uart_port *port)
static void mcf_stop_rx(struct uart_port *port)
{
struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
pp->imr &= ~MCFUART_UIR_RXREADY;
writeb(pp->imr, port->membase + MCFUART_UIMR);
spin_unlock_irqrestore(&port->lock, flags);
}
/****************************************************************************/
@ -366,13 +352,22 @@ static irqreturn_t mcf_interrupt(int irq, void *data)
struct uart_port *port = data;
struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
unsigned int isr;
irqreturn_t ret = IRQ_NONE;
isr = readb(port->membase + MCFUART_UISR) & pp->imr;
if (isr & MCFUART_UIR_RXREADY)
spin_lock(&port->lock);
if (isr & MCFUART_UIR_RXREADY) {
mcf_rx_chars(pp);
if (isr & MCFUART_UIR_TXREADY)
ret = IRQ_HANDLED;
}
if (isr & MCFUART_UIR_TXREADY) {
mcf_tx_chars(pp);
return IRQ_HANDLED;
ret = IRQ_HANDLED;
}
spin_unlock(&port->lock);
return ret;
}
/****************************************************************************/

1498
drivers/serial/mfd.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -1298,7 +1298,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
};
static int __devinit
mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
mpc52xx_uart_of_probe(struct platform_device *op, const struct of_device_id *match)
{
int idx = -1;
unsigned int uartclk;
@ -1369,7 +1369,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
}
static int
mpc52xx_uart_of_remove(struct of_device *op)
mpc52xx_uart_of_remove(struct platform_device *op)
{
struct uart_port *port = dev_get_drvdata(&op->dev);
dev_set_drvdata(&op->dev, NULL);
@ -1382,7 +1382,7 @@ mpc52xx_uart_of_remove(struct of_device *op)
#ifdef CONFIG_PM
static int
mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state)
mpc52xx_uart_of_suspend(struct platform_device *op, pm_message_t state)
{
struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
@ -1393,7 +1393,7 @@ mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state)
}
static int
mpc52xx_uart_of_resume(struct of_device *op)
mpc52xx_uart_of_resume(struct platform_device *op)
{
struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);

View file

@ -0,0 +1,844 @@
/*
* max3110.c - spi uart protocol driver for Maxim 3110 on Moorestown
*
* Copyright (C) Intel 2008 Feng Tang <feng.tang@intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Note:
* 1. From Max3110 spec, the Rx FIFO has 8 words, while the Tx FIFO only has
* 1 word. If SPI master controller doesn't support sclk frequency change,
* then the char need be sent out one by one with some delay
*
* 2. Currently only RX availabe interrrupt is used, no need for waiting TXE
* interrupt for a low speed UART device
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <asm/atomic.h>
#include <linux/spi/spi.h>
#include <linux/spi/dw_spi.h>
#include "mrst_max3110.h"
#define PR_FMT "mrst_max3110: "
#define UART_TX_NEEDED 1
#define CON_TX_NEEDED 2
#define BIT_IRQ_PENDING 3
struct uart_max3110 {
struct uart_port port;
struct spi_device *spi;
char *name;
wait_queue_head_t wq;
struct task_struct *main_thread;
struct task_struct *read_thread;
struct mutex thread_mutex;;
u32 baud;
u16 cur_conf;
u8 clock;
u8 parity, word_7bits;
unsigned long uart_flags;
/* console related */
struct circ_buf con_xmit;
/* irq related */
u16 irq;
};
/* global data structure, may need be removed */
struct uart_max3110 *pmax;
static inline void receive_char(struct uart_max3110 *max, u8 ch);
static void receive_chars(struct uart_max3110 *max,
unsigned char *str, int len);
static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf);
static void max3110_console_receive(struct uart_max3110 *max);
int max3110_write_then_read(struct uart_max3110 *max,
const u8 *txbuf, u8 *rxbuf, unsigned len, int always_fast)
{
struct spi_device *spi = max->spi;
struct spi_message message;
struct spi_transfer x;
int ret;
if (!txbuf || !rxbuf)
return -EINVAL;
spi_message_init(&message);
memset(&x, 0, sizeof x);
x.len = len;
x.tx_buf = txbuf;
x.rx_buf = rxbuf;
spi_message_add_tail(&x, &message);
if (always_fast)
x.speed_hz = 3125000;
else if (max->baud)
x.speed_hz = max->baud;
/* Do the i/o */
ret = spi_sync(spi, &message);
return ret;
}
/* Write a u16 to the device, and return one u16 read back */
int max3110_out(struct uart_max3110 *max, const u16 out)
{
u16 tmp;
int ret;
ret = max3110_write_then_read(max, (u8 *)&out, (u8 *)&tmp, 2, 1);
if (ret)
return ret;
/* If some valid data is read back */
if (tmp & MAX3110_READ_DATA_AVAILABLE)
receive_char(max, (tmp & 0xff));
return ret;
}
#define MAX_READ_LEN 20
/*
* This is usually used to read data from SPIC RX FIFO, which doesn't
* need any delay like flushing character out. It returns how many
* valide bytes are read back
*/
static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf)
{
u16 out[MAX_READ_LEN], in[MAX_READ_LEN];
u8 *pbuf, valid_str[MAX_READ_LEN];
int i, j, bytelen;
if (len > MAX_READ_LEN) {
pr_err(PR_FMT "read len %d is too large\n", len);
return 0;
}
bytelen = len * 2;
memset(out, 0, bytelen);
memset(in, 0, bytelen);
if (max3110_write_then_read(max, (u8 *)out, (u8 *)in, bytelen, 1))
return 0;
/* If caller don't provide a buffer, then handle received char */
pbuf = buf ? buf : valid_str;
for (i = 0, j = 0; i < len; i++) {
if (in[i] & MAX3110_READ_DATA_AVAILABLE)
pbuf[j++] = (u8)(in[i] & 0xff);
}
if (j && (pbuf == valid_str))
receive_chars(max, valid_str, j);
return j;
}
static void serial_m3110_con_putchar(struct uart_port *port, int ch)
{
struct uart_max3110 *max =
container_of(port, struct uart_max3110, port);
struct circ_buf *xmit = &max->con_xmit;
if (uart_circ_chars_free(xmit)) {
xmit->buf[xmit->head] = (char)ch;
xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1);
}
if (!test_and_set_bit(CON_TX_NEEDED, &max->uart_flags))
wake_up_process(max->main_thread);
}
/*
* Print a string to the serial port trying not to disturb
* any possible real use of the port...
*
* The console_lock must be held when we get here.
*/
static void serial_m3110_con_write(struct console *co,
const char *s, unsigned int count)
{
if (!pmax)
return;
uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar);
}
static int __init
serial_m3110_con_setup(struct console *co, char *options)
{
struct uart_max3110 *max = pmax;
int baud = 115200;
int bits = 8;
int parity = 'n';
int flow = 'n';
pr_info(PR_FMT "setting up console\n");
if (!max) {
pr_err(PR_FMT "pmax is NULL, return");
return -ENODEV;
}
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
return uart_set_options(&max->port, co, baud, parity, bits, flow);
}
static struct tty_driver *serial_m3110_con_device(struct console *co,
int *index)
{
struct uart_driver *p = co->data;
*index = co->index;
return p->tty_driver;
}
static struct uart_driver serial_m3110_reg;
static struct console serial_m3110_console = {
.name = "ttyS",
.write = serial_m3110_con_write,
.device = serial_m3110_con_device,
.setup = serial_m3110_con_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
.data = &serial_m3110_reg,
};
#define MRST_CONSOLE (&serial_m3110_console)
static unsigned int serial_m3110_tx_empty(struct uart_port *port)
{
return 1;
}
static void serial_m3110_stop_tx(struct uart_port *port)
{
return;
}
/* stop_rx will be called in spin_lock env */
static void serial_m3110_stop_rx(struct uart_port *port)
{
return;
}
#define WORDS_PER_XFER 128
static inline void send_circ_buf(struct uart_max3110 *max,
struct circ_buf *xmit)
{
int len, left = 0;
u16 obuf[WORDS_PER_XFER], ibuf[WORDS_PER_XFER];
u8 valid_str[WORDS_PER_XFER];
int i, j;
while (!uart_circ_empty(xmit)) {
left = uart_circ_chars_pending(xmit);
while (left) {
len = (left >= WORDS_PER_XFER) ? WORDS_PER_XFER : left;
memset(obuf, 0, len * 2);
memset(ibuf, 0, len * 2);
for (i = 0; i < len; i++) {
obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG;
xmit->tail = (xmit->tail + 1) &
(UART_XMIT_SIZE - 1);
}
max3110_write_then_read(max, (u8 *)obuf,
(u8 *)ibuf, len * 2, 0);
for (i = 0, j = 0; i < len; i++) {
if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
valid_str[j++] = (u8)(ibuf[i] & 0xff);
}
if (j)
receive_chars(max, valid_str, j);
max->port.icount.tx += len;
left -= len;
}
}
}
static void transmit_char(struct uart_max3110 *max)
{
struct uart_port *port = &max->port;
struct circ_buf *xmit = &port->state->xmit;
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
return;
send_circ_buf(max, xmit);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
if (uart_circ_empty(xmit))
serial_m3110_stop_tx(port);
}
/* This will be called by uart_write() and tty_write, can't
* go to sleep */
static void serial_m3110_start_tx(struct uart_port *port)
{
struct uart_max3110 *max =
container_of(port, struct uart_max3110, port);
if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags))
wake_up_process(max->main_thread);
}
static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
{
struct uart_port *port = &max->port;
struct tty_struct *tty;
int usable;
/* If uart is not opened, just return */
if (!port->state)
return;
tty = port->state->port.tty;
if (!tty)
return; /* receive some char before the tty is opened */
while (len) {
usable = tty_buffer_request_room(tty, len);
if (usable) {
tty_insert_flip_string(tty, str, usable);
str += usable;
port->icount.rx += usable;
tty_flip_buffer_push(tty);
}
len -= usable;
}
}
static inline void receive_char(struct uart_max3110 *max, u8 ch)
{
receive_chars(max, &ch, 1);
}
static void max3110_console_receive(struct uart_max3110 *max)
{
int loop = 1, num, total = 0;
u8 recv_buf[512], *pbuf;
pbuf = recv_buf;
do {
num = max3110_read_multi(max, 8, pbuf);
if (num) {
loop = 10;
pbuf += num;
total += num;
if (total >= 500) {
receive_chars(max, recv_buf, total);
pbuf = recv_buf;
total = 0;
}
}
} while (--loop);
if (total)
receive_chars(max, recv_buf, total);
}
static int max3110_main_thread(void *_max)
{
struct uart_max3110 *max = _max;
wait_queue_head_t *wq = &max->wq;
int ret = 0;
struct circ_buf *xmit = &max->con_xmit;
init_waitqueue_head(wq);
pr_info(PR_FMT "start main thread\n");
do {
wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop());
mutex_lock(&max->thread_mutex);
if (test_and_clear_bit(BIT_IRQ_PENDING, &max->uart_flags))
max3110_console_receive(max);
/* first handle console output */
if (test_and_clear_bit(CON_TX_NEEDED, &max->uart_flags))
send_circ_buf(max, xmit);
/* handle uart output */
if (test_and_clear_bit(UART_TX_NEEDED, &max->uart_flags))
transmit_char(max);
mutex_unlock(&max->thread_mutex);
} while (!kthread_should_stop());
return ret;
}
#ifdef CONFIG_MRST_MAX3110_IRQ
static irqreturn_t serial_m3110_irq(int irq, void *dev_id)
{
struct uart_max3110 *max = dev_id;
/* max3110's irq is a falling edge, not level triggered,
* so no need to disable the irq */
if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags))
wake_up_process(max->main_thread);
return IRQ_HANDLED;
}
#else
/* if don't use RX IRQ, then need a thread to polling read */
static int max3110_read_thread(void *_max)
{
struct uart_max3110 *max = _max;
pr_info(PR_FMT "start read thread\n");
do {
mutex_lock(&max->thread_mutex);
max3110_console_receive(max);
mutex_unlock(&max->thread_mutex);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 20);
} while (!kthread_should_stop());
return 0;
}
#endif
static int serial_m3110_startup(struct uart_port *port)
{
struct uart_max3110 *max =
container_of(port, struct uart_max3110, port);
u16 config = 0;
int ret = 0;
if (port->line != 0)
pr_err(PR_FMT "uart port startup failed\n");
/* firstly disable all IRQ and config it to 115200, 8n1 */
config = WC_TAG | WC_FIFO_ENABLE
| WC_1_STOPBITS
| WC_8BIT_WORD
| WC_BAUD_DR2;
ret = max3110_out(max, config);
/* as we use thread to handle tx/rx, need set low latency */
port->state->port.tty->low_latency = 1;
#ifdef CONFIG_MRST_MAX3110_IRQ
ret = request_irq(max->irq, serial_m3110_irq,
IRQ_TYPE_EDGE_FALLING, "max3110", max);
if (ret)
return ret;
/* enable RX IRQ only */
config |= WC_RXA_IRQ_ENABLE;
max3110_out(max, config);
#else
/* if IRQ is disabled, start a read thread for input data */
max->read_thread =
kthread_run(max3110_read_thread, max, "max3110_read");
#endif
max->cur_conf = config;
return 0;
}
static void serial_m3110_shutdown(struct uart_port *port)
{
struct uart_max3110 *max =
container_of(port, struct uart_max3110, port);
u16 config;
if (max->read_thread) {
kthread_stop(max->read_thread);
max->read_thread = NULL;
}
#ifdef CONFIG_MRST_MAX3110_IRQ
free_irq(max->irq, max);
#endif
/* Disable interrupts from this port */
config = WC_TAG | WC_SW_SHDI;
max3110_out(max, config);
}
static void serial_m3110_release_port(struct uart_port *port)
{
}
static int serial_m3110_request_port(struct uart_port *port)
{
return 0;
}
static void serial_m3110_config_port(struct uart_port *port, int flags)
{
/* give it fake type */
port->type = PORT_PXA;
}
static int
serial_m3110_verify_port(struct uart_port *port, struct serial_struct *ser)
{
/* we don't want the core code to modify any port params */
return -EINVAL;
}
static const char *serial_m3110_type(struct uart_port *port)
{
struct uart_max3110 *max =
container_of(port, struct uart_max3110, port);
return max->name;
}
static void
serial_m3110_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct uart_max3110 *max =
container_of(port, struct uart_max3110, port);
unsigned char cval;
unsigned int baud, parity = 0;
int clk_div = -1;
u16 new_conf = max->cur_conf;
switch (termios->c_cflag & CSIZE) {
case CS7:
cval = UART_LCR_WLEN7;
new_conf |= WC_7BIT_WORD;
break;
default:
case CS8:
cval = UART_LCR_WLEN8;
new_conf |= WC_8BIT_WORD;
break;
}
baud = uart_get_baud_rate(port, termios, old, 0, 230400);
/* first calc the div for 1.8MHZ clock case */
switch (baud) {
case 300:
clk_div = WC_BAUD_DR384;
break;
case 600:
clk_div = WC_BAUD_DR192;
break;
case 1200:
clk_div = WC_BAUD_DR96;
break;
case 2400:
clk_div = WC_BAUD_DR48;
break;
case 4800:
clk_div = WC_BAUD_DR24;
break;
case 9600:
clk_div = WC_BAUD_DR12;
break;
case 19200:
clk_div = WC_BAUD_DR6;
break;
case 38400:
clk_div = WC_BAUD_DR3;
break;
case 57600:
clk_div = WC_BAUD_DR2;
break;
case 115200:
clk_div = WC_BAUD_DR1;
break;
case 230400:
if (max->clock & MAX3110_HIGH_CLK)
break;
default:
/* pick the previous baud rate */
baud = max->baud;
clk_div = max->cur_conf & WC_BAUD_DIV_MASK;
tty_termios_encode_baud_rate(termios, baud, baud);
}
if (max->clock & MAX3110_HIGH_CLK) {
clk_div += 1;
/* high clk version max3110 doesn't support B300 */
if (baud == 300)
baud = 600;
if (baud == 230400)
clk_div = WC_BAUD_DR1;
tty_termios_encode_baud_rate(termios, baud, baud);
}
new_conf = (new_conf & ~WC_BAUD_DIV_MASK) | clk_div;
if (termios->c_cflag & CSTOPB)
new_conf |= WC_2_STOPBITS;
else
new_conf &= ~WC_2_STOPBITS;
if (termios->c_cflag & PARENB) {
new_conf |= WC_PARITY_ENABLE;
parity |= UART_LCR_PARITY;
} else
new_conf &= ~WC_PARITY_ENABLE;
if (!(termios->c_cflag & PARODD))
parity |= UART_LCR_EPAR;
max->parity = parity;
uart_update_timeout(port, termios->c_cflag, baud);
new_conf |= WC_TAG;
if (new_conf != max->cur_conf) {
max3110_out(max, new_conf);
max->cur_conf = new_conf;
max->baud = baud;
}
}
/* don't handle hw handshaking */
static unsigned int serial_m3110_get_mctrl(struct uart_port *port)
{
return TIOCM_DSR | TIOCM_CAR | TIOCM_DSR;
}
static void serial_m3110_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
}
static void serial_m3110_break_ctl(struct uart_port *port, int break_state)
{
}
static void serial_m3110_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
}
static void serial_m3110_enable_ms(struct uart_port *port)
{
}
struct uart_ops serial_m3110_ops = {
.tx_empty = serial_m3110_tx_empty,
.set_mctrl = serial_m3110_set_mctrl,
.get_mctrl = serial_m3110_get_mctrl,
.stop_tx = serial_m3110_stop_tx,
.start_tx = serial_m3110_start_tx,
.stop_rx = serial_m3110_stop_rx,
.enable_ms = serial_m3110_enable_ms,
.break_ctl = serial_m3110_break_ctl,
.startup = serial_m3110_startup,
.shutdown = serial_m3110_shutdown,
.set_termios = serial_m3110_set_termios, /* must have */
.pm = serial_m3110_pm,
.type = serial_m3110_type,
.release_port = serial_m3110_release_port,
.request_port = serial_m3110_request_port,
.config_port = serial_m3110_config_port,
.verify_port = serial_m3110_verify_port,
};
static struct uart_driver serial_m3110_reg = {
.owner = THIS_MODULE,
.driver_name = "MRST serial",
.dev_name = "ttyS",
.major = TTY_MAJOR,
.minor = 64,
.nr = 1,
.cons = MRST_CONSOLE,
};
static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state)
{
return 0;
}
static int serial_m3110_resume(struct spi_device *spi)
{
return 0;
}
static struct dw_spi_chip spi0_uart = {
.poll_mode = 1,
.enable_dma = 0,
.type = SPI_FRF_SPI,
};
static int serial_m3110_probe(struct spi_device *spi)
{
struct uart_max3110 *max;
int ret;
unsigned char *buffer;
u16 res;
max = kzalloc(sizeof(*max), GFP_KERNEL);
if (!max)
return -ENOMEM;
/* set spi info */
spi->mode = SPI_MODE_0;
spi->bits_per_word = 16;
max->clock = MAX3110_HIGH_CLK;
spi->controller_data = &spi0_uart;
spi_setup(spi);
max->port.type = PORT_PXA; /* need apply for a max3110 type */
max->port.fifosize = 2; /* only have 16b buffer */
max->port.ops = &serial_m3110_ops;
max->port.line = 0;
max->port.dev = &spi->dev;
max->port.uartclk = 115200;
max->spi = spi;
max->name = spi->modalias; /* use spi name as the name */
max->irq = (u16)spi->irq;
mutex_init(&max->thread_mutex);
max->word_7bits = 0;
max->parity = 0;
max->baud = 0;
max->cur_conf = 0;
max->uart_flags = 0;
/* Check if reading configuration register returns something sane */
res = RC_TAG;
ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0);
if (ret < 0 || res == 0 || res == 0xffff) {
printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)",
res);
ret = -ENODEV;
goto err_get_page;
}
buffer = (unsigned char *)__get_free_page(GFP_KERNEL);
if (!buffer) {
ret = -ENOMEM;
goto err_get_page;
}
max->con_xmit.buf = (unsigned char *)buffer;
max->con_xmit.head = max->con_xmit.tail = 0;
max->main_thread = kthread_run(max3110_main_thread,
max, "max3110_main");
if (IS_ERR(max->main_thread)) {
ret = PTR_ERR(max->main_thread);
goto err_kthread;
}
pmax = max;
/* give membase a psudo value to pass serial_core's check */
max->port.membase = (void *)0xff110000;
uart_add_one_port(&serial_m3110_reg, &max->port);
return 0;
err_kthread:
free_page((unsigned long)buffer);
err_get_page:
pmax = NULL;
kfree(max);
return ret;
}
static int max3110_remove(struct spi_device *dev)
{
struct uart_max3110 *max = pmax;
if (!pmax)
return 0;
pmax = NULL;
uart_remove_one_port(&serial_m3110_reg, &max->port);
free_page((unsigned long)max->con_xmit.buf);
if (max->main_thread)
kthread_stop(max->main_thread);
kfree(max);
return 0;
}
static struct spi_driver uart_max3110_driver = {
.driver = {
.name = "spi_max3111",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = serial_m3110_probe,
.remove = __devexit_p(max3110_remove),
.suspend = serial_m3110_suspend,
.resume = serial_m3110_resume,
};
int __init serial_m3110_init(void)
{
int ret = 0;
ret = uart_register_driver(&serial_m3110_reg);
if (ret)
return ret;
ret = spi_register_driver(&uart_max3110_driver);
if (ret)
uart_unregister_driver(&serial_m3110_reg);
return ret;
}
void __exit serial_m3110_exit(void)
{
spi_unregister_driver(&uart_max3110_driver);
uart_unregister_driver(&serial_m3110_reg);
}
module_init(serial_m3110_init);
module_exit(serial_m3110_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("max3110-uart");

View file

@ -0,0 +1,59 @@
#ifndef _MRST_MAX3110_H
#define _MRST_MAX3110_H
#define MAX3110_HIGH_CLK 0x1 /* 3.6864 MHZ */
#define MAX3110_LOW_CLK 0x0 /* 1.8432 MHZ */
/* status bits for all 4 MAX3110 operate modes */
#define MAX3110_READ_DATA_AVAILABLE (1 << 15)
#define MAX3110_WRITE_BUF_EMPTY (1 << 14)
#define WC_TAG (3 << 14)
#define RC_TAG (1 << 14)
#define WD_TAG (2 << 14)
#define RD_TAG (0 << 14)
/* bits def for write configuration */
#define WC_FIFO_ENABLE_MASK (1 << 13)
#define WC_FIFO_ENABLE (0 << 13)
#define WC_SW_SHDI (1 << 12)
#define WC_IRQ_MASK (0xF << 8)
#define WC_TXE_IRQ_ENABLE (1 << 11) /* TX empty irq */
#define WC_RXA_IRQ_ENABLE (1 << 10) /* RX availabe irq */
#define WC_PAR_HIGH_IRQ_ENABLE (1 << 9)
#define WC_REC_ACT_IRQ_ENABLE (1 << 8)
#define WC_IRDA_ENABLE (1 << 7)
#define WC_STOPBITS_MASK (1 << 6)
#define WC_2_STOPBITS (1 << 6)
#define WC_1_STOPBITS (0 << 6)
#define WC_PARITY_ENABLE_MASK (1 << 5)
#define WC_PARITY_ENABLE (1 << 5)
#define WC_WORDLEN_MASK (1 << 4)
#define WC_7BIT_WORD (1 << 4)
#define WC_8BIT_WORD (0 << 4)
#define WC_BAUD_DIV_MASK (0xF)
#define WC_BAUD_DR1 (0x0)
#define WC_BAUD_DR2 (0x1)
#define WC_BAUD_DR4 (0x2)
#define WC_BAUD_DR8 (0x3)
#define WC_BAUD_DR16 (0x4)
#define WC_BAUD_DR32 (0x5)
#define WC_BAUD_DR64 (0x6)
#define WC_BAUD_DR128 (0x7)
#define WC_BAUD_DR3 (0x8)
#define WC_BAUD_DR6 (0x9)
#define WC_BAUD_DR12 (0xA)
#define WC_BAUD_DR24 (0xB)
#define WC_BAUD_DR48 (0xC)
#define WC_BAUD_DR96 (0xD)
#define WC_BAUD_DR192 (0xE)
#define WC_BAUD_DR384 (0xF)
#endif

View file

@ -344,7 +344,7 @@ int nwpserial_register_port(struct uart_port *port)
mutex_lock(&nwpserial_mutex);
dn = to_of_device(port->dev)->dev.of_node;
dn = port->dev->of_node;
if (dn == NULL)
goto out;

View file

@ -27,7 +27,7 @@ struct of_serial_info {
/*
* Fill a struct uart_port for a given device node
*/
static int __devinit of_platform_serial_setup(struct of_device *ofdev,
static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
int type, struct uart_port *port)
{
struct resource resource;
@ -80,7 +80,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
/*
* Try to register a serial port
*/
static int __devinit of_platform_serial_probe(struct of_device *ofdev,
static int __devinit of_platform_serial_probe(struct platform_device *ofdev,
const struct of_device_id *id)
{
struct of_serial_info *info;
@ -134,7 +134,7 @@ out:
/*
* Release a line
*/
static int of_platform_serial_remove(struct of_device *ofdev)
static int of_platform_serial_remove(struct platform_device *ofdev)
{
struct of_serial_info *info = dev_get_drvdata(&ofdev->dev);
switch (info->type) {

View file

@ -28,8 +28,12 @@
static int s5pv210_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
struct s3c2410_uartcfg *cfg = port->dev->platform_data;
unsigned long ucon = rd_regl(port, S3C2410_UCON);
if ((cfg->clocks_size) == 1)
return 0;
if (strcmp(clk->name, "pclk") == 0)
ucon &= ~S5PV210_UCON_CLKMASK;
else if (strcmp(clk->name, "uclk1") == 0)
@ -47,10 +51,14 @@ static int s5pv210_serial_setsource(struct uart_port *port,
static int s5pv210_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
struct s3c2410_uartcfg *cfg = port->dev->platform_data;
u32 ucon = rd_regl(port, S3C2410_UCON);
clk->divisor = 1;
if ((cfg->clocks_size) == 1)
return 0;
switch (ucon & S5PV210_UCON_CLKMASK) {
case S5PV210_UCON_PCLK:
clk->name = "pclk";

View file

@ -705,8 +705,13 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
if (ourport->info->has_divslot) {
unsigned int div = ourport->baudclk_rate / baud;
udivslot = udivslot_table[div & 15];
dbg("udivslot = %04x (div %d)\n", udivslot, div & 15);
if (cfg->has_fracval) {
udivslot = (div & 15);
dbg("fracval = %04x\n", udivslot);
} else {
udivslot = udivslot_table[div & 15];
dbg("udivslot = %04x (div %d)\n", udivslot, div & 15);
}
}
switch (termios->c_cflag & CSIZE) {

View file

@ -58,9 +58,9 @@ static struct lock_class_key port_lock_key;
#define uart_console(port) (0)
#endif
static void uart_change_speed(struct uart_state *state,
static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
struct ktermios *old_termios);
static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
static void __uart_wait_until_sent(struct uart_port *port, int timeout);
static void uart_change_pm(struct uart_state *state, int pm_state);
/*
@ -137,7 +137,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
* Startup the port. This will be called once per open. All calls
* will be serialised by the per-port mutex.
*/
static int uart_startup(struct uart_state *state, int init_hw)
static int uart_startup(struct tty_struct *tty, struct uart_state *state, int init_hw)
{
struct uart_port *uport = state->uart_port;
struct tty_port *port = &state->port;
@ -152,7 +152,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* once we have successfully opened the port. Also set
* up the tty->alt_speed kludge
*/
set_bit(TTY_IO_ERROR, &port->tty->flags);
set_bit(TTY_IO_ERROR, &tty->flags);
if (uport->type == PORT_UNKNOWN)
return 0;
@ -177,26 +177,26 @@ static int uart_startup(struct uart_state *state, int init_hw)
/*
* Initialise the hardware port settings.
*/
uart_change_speed(state, NULL);
uart_change_speed(tty, state, NULL);
/*
* Setup the RTS and DTR signals once the
* port is open and ready to respond.
*/
if (port->tty->termios->c_cflag & CBAUD)
if (tty->termios->c_cflag & CBAUD)
uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
}
if (port->flags & ASYNC_CTS_FLOW) {
spin_lock_irq(&uport->lock);
if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
port->tty->hw_stopped = 1;
tty->hw_stopped = 1;
spin_unlock_irq(&uport->lock);
}
set_bit(ASYNCB_INITIALIZED, &port->flags);
clear_bit(TTY_IO_ERROR, &port->tty->flags);
clear_bit(TTY_IO_ERROR, &tty->flags);
}
if (retval && capable(CAP_SYS_ADMIN))
@ -210,11 +210,10 @@ static int uart_startup(struct uart_state *state, int init_hw)
* DTR is dropped if the hangup on close termio flag is on. Calls to
* uart_shutdown are serialised by the per-port semaphore.
*/
static void uart_shutdown(struct uart_state *state)
static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
{
struct uart_port *uport = state->uart_port;
struct tty_port *port = &state->port;
struct tty_struct *tty = port->tty;
/*
* Set the TTY IO error marker
@ -430,11 +429,10 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
EXPORT_SYMBOL(uart_get_divisor);
/* FIXME: Consistent locking policy */
static void
uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
struct ktermios *old_termios)
{
struct tty_port *port = &state->port;
struct tty_struct *tty = port->tty;
struct uart_port *uport = state->uart_port;
struct ktermios *termios;
@ -463,8 +461,8 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
uport->ops->set_termios(uport, termios, old_termios);
}
static inline int
__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
static inline int __uart_put_char(struct uart_port *port,
struct circ_buf *circ, unsigned char c)
{
unsigned long flags;
int ret = 0;
@ -494,8 +492,8 @@ static void uart_flush_chars(struct tty_struct *tty)
uart_start(tty);
}
static int
uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
static int uart_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port;
@ -675,7 +673,7 @@ static int uart_get_info(struct uart_state *state,
return 0;
}
static int uart_set_info(struct uart_state *state,
static int uart_set_info(struct tty_struct *tty, struct uart_state *state,
struct serial_struct __user *newinfo)
{
struct serial_struct new_serial;
@ -770,7 +768,7 @@ static int uart_set_info(struct uart_state *state,
* We need to shutdown the serial port at the old
* port/type/irq combination.
*/
uart_shutdown(state);
uart_shutdown(tty, state);
}
if (change_port) {
@ -869,25 +867,27 @@ static int uart_set_info(struct uart_state *state,
"is deprecated.\n", current->comm,
tty_name(port->tty, buf));
}
uart_change_speed(state, NULL);
uart_change_speed(tty, state, NULL);
}
} else
retval = uart_startup(state, 1);
retval = uart_startup(tty, state, 1);
exit:
mutex_unlock(&port->mutex);
return retval;
}
/*
* uart_get_lsr_info - get line status register info.
* Note: uart_ioctl protects us against hangups.
/**
* uart_get_lsr_info - get line status register info
* @tty: tty associated with the UART
* @state: UART being queried
* @value: returned modem value
*
* Note: uart_ioctl protects us against hangups.
*/
static int uart_get_lsr_info(struct uart_state *state,
unsigned int __user *value)
static int uart_get_lsr_info(struct tty_struct *tty,
struct uart_state *state, unsigned int __user *value)
{
struct uart_port *uport = state->uart_port;
struct tty_port *port = &state->port;
unsigned int result;
result = uport->ops->tx_empty(uport);
@ -900,7 +900,7 @@ static int uart_get_lsr_info(struct uart_state *state,
*/
if (uport->x_char ||
((uart_circ_chars_pending(&state->xmit) > 0) &&
!port->tty->stopped && !port->tty->hw_stopped))
!tty->stopped && !tty->hw_stopped))
result &= ~TIOCSER_TEMT;
return put_user(result, value);
@ -961,7 +961,7 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state)
return 0;
}
static int uart_do_autoconfig(struct uart_state *state)
static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
{
struct uart_port *uport = state->uart_port;
struct tty_port *port = &state->port;
@ -980,7 +980,7 @@ static int uart_do_autoconfig(struct uart_state *state)
ret = -EBUSY;
if (tty_port_users(port) == 1) {
uart_shutdown(state);
uart_shutdown(tty, state);
/*
* If we already have a port type configured,
@ -999,7 +999,7 @@ static int uart_do_autoconfig(struct uart_state *state)
*/
uport->ops->config_port(uport, flags);
ret = uart_startup(state, 1);
ret = uart_startup(tty, state, 1);
}
mutex_unlock(&port->mutex);
return ret;
@ -1122,11 +1122,11 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
break;
case TIOCSSERIAL:
ret = uart_set_info(state, uarg);
ret = uart_set_info(tty, state, uarg);
break;
case TIOCSERCONFIG:
ret = uart_do_autoconfig(state);
ret = uart_do_autoconfig(tty, state);
break;
case TIOCSERGWILD: /* obsolete */
@ -1172,7 +1172,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
*/
switch (cmd) {
case TIOCSERGETLSR: /* Get line status register */
ret = uart_get_lsr_info(state, uarg);
ret = uart_get_lsr_info(tty, state, uarg);
break;
default: {
@ -1194,7 +1194,7 @@ static void uart_set_ldisc(struct tty_struct *tty)
struct uart_port *uport = state->uart_port;
if (uport->ops->set_ldisc)
uport->ops->set_ldisc(uport);
uport->ops->set_ldisc(uport, tty->termios->c_line);
}
static void uart_set_termios(struct tty_struct *tty,
@ -1219,7 +1219,7 @@ static void uart_set_termios(struct tty_struct *tty,
return;
}
uart_change_speed(state, old_termios);
uart_change_speed(tty, state, old_termios);
/* Handle transition to B0 status */
if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
@ -1272,8 +1272,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
struct uart_state *state = tty->driver_data;
struct tty_port *port;
struct uart_port *uport;
unsigned long flags;
BUG_ON(!kernel_locked());
BUG_ON(!tty_locked());
if (!state)
return;
@ -1284,9 +1285,12 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
pr_debug("uart_close(%d) called\n", uport->line);
mutex_lock(&port->mutex);
spin_lock_irqsave(&port->lock, flags);
if (tty_hung_up_p(filp))
if (tty_hung_up_p(filp)) {
spin_unlock_irqrestore(&port->lock, flags);
goto done;
}
if ((tty->count == 1) && (port->count != 1)) {
/*
@ -1305,8 +1309,10 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
tty->name, port->count);
port->count = 0;
}
if (port->count)
if (port->count) {
spin_unlock_irqrestore(&port->lock, flags);
goto done;
}
/*
* Now we wait for the transmit buffer to clear; and we notify
@ -1314,9 +1320,18 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* setting tty->closing.
*/
tty->closing = 1;
spin_unlock_irqrestore(&port->lock, flags);
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
/*
* hack: open-coded tty_wait_until_sent to avoid
* recursive tty_lock
*/
long timeout = msecs_to_jiffies(port->closing_wait);
if (wait_event_interruptible_timeout(tty->write_wait,
!tty_chars_in_buffer(tty), timeout) >= 0)
__uart_wait_until_sent(uport, timeout);
}
/*
* At this point, we stop accepting input. To do this, we
@ -1332,45 +1347,47 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* has completely drained; this is especially
* important if there is a transmit FIFO!
*/
uart_wait_until_sent(tty, uport->timeout);
__uart_wait_until_sent(uport, uport->timeout);
}
uart_shutdown(state);
uart_shutdown(tty, state);
uart_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
tty_port_tty_set(port, NULL);
spin_lock_irqsave(&port->lock, flags);
tty->closing = 0;
if (port->blocked_open) {
spin_unlock_irqrestore(&port->lock, flags);
if (port->close_delay)
msleep_interruptible(port->close_delay);
spin_lock_irqsave(&port->lock, flags);
} else if (!uart_console(uport)) {
spin_unlock_irqrestore(&port->lock, flags);
uart_change_pm(state, 3);
spin_lock_irqsave(&port->lock, flags);
}
/*
* Wake up anyone trying to open this port.
*/
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
spin_unlock_irqrestore(&port->lock, flags);
wake_up_interruptible(&port->open_wait);
done:
mutex_unlock(&port->mutex);
}
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
static void __uart_wait_until_sent(struct uart_port *port, int timeout)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
unsigned long char_time, expire;
if (port->type == PORT_UNKNOWN || port->fifosize == 0)
return;
lock_kernel();
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
@ -1416,7 +1433,16 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
break;
}
set_current_state(TASK_RUNNING); /* might not be needed */
unlock_kernel();
}
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
tty_lock();
__uart_wait_until_sent(port, timeout);
tty_unlock();
}
/*
@ -1429,16 +1455,19 @@ static void uart_hangup(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
struct tty_port *port = &state->port;
unsigned long flags;
BUG_ON(!kernel_locked());
BUG_ON(!tty_locked());
pr_debug("uart_hangup(%d)\n", state->uart_port->line);
mutex_lock(&port->mutex);
if (port->flags & ASYNC_NORMAL_ACTIVE) {
uart_flush_buffer(tty);
uart_shutdown(state);
uart_shutdown(tty, state);
spin_lock_irqsave(&port->lock, flags);
port->count = 0;
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
spin_unlock_irqrestore(&port->lock, flags);
tty_port_tty_set(port, NULL);
wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&port->delta_msr_wait);
@ -1446,15 +1475,19 @@ static void uart_hangup(struct tty_struct *tty)
mutex_unlock(&port->mutex);
}
/*
* Copy across the serial console cflag setting into the termios settings
* for the initial open of the port. This allows continuity between the
* kernel settings, and the settings init adopts when it opens the port
* for the first time.
/**
* uart_update_termios - update the terminal hw settings
* @tty: tty associated with UART
* @state: UART to update
*
* Copy across the serial console cflag setting into the termios settings
* for the initial open of the port. This allows continuity between the
* kernel settings, and the settings init adopts when it opens the port
* for the first time.
*/
static void uart_update_termios(struct uart_state *state)
static void uart_update_termios(struct tty_struct *tty,
struct uart_state *state)
{
struct tty_struct *tty = state->port.tty;
struct uart_port *port = state->uart_port;
if (uart_console(port) && port->cons->cflag) {
@ -1471,7 +1504,7 @@ static void uart_update_termios(struct uart_state *state)
/*
* Make termios settings take effect.
*/
uart_change_speed(state, NULL);
uart_change_speed(tty, state, NULL);
/*
* And finally enable the RTS and DTR signals.
@ -1481,92 +1514,39 @@ static void uart_update_termios(struct uart_state *state)
}
}
/*
* Block the open until the port is ready. We must be called with
* the per-port semaphore held.
*/
static int
uart_block_til_ready(struct file *filp, struct uart_state *state)
static int uart_carrier_raised(struct tty_port *port)
{
DECLARE_WAITQUEUE(wait, current);
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport = state->uart_port;
struct tty_port *port = &state->port;
unsigned int mctrl;
port->blocked_open++;
port->count--;
add_wait_queue(&port->open_wait, &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
/*
* If we have been hung up, tell userspace/restart open.
*/
if (tty_hung_up_p(filp) || port->tty == NULL)
break;
/*
* If the port has been closed, tell userspace/restart open.
*/
if (!(port->flags & ASYNC_INITIALIZED))
break;
/*
* If non-blocking mode is set, or CLOCAL mode is set,
* we don't want to wait for the modem status lines to
* indicate that the port is ready.
*
* Also, if the port is not enabled/configured, we want
* to allow the open to succeed here. Note that we will
* have set TTY_IO_ERROR for a non-existant port.
*/
if ((filp->f_flags & O_NONBLOCK) ||
(port->tty->termios->c_cflag & CLOCAL) ||
(port->tty->flags & (1 << TTY_IO_ERROR)))
break;
/*
* Set DTR to allow modem to know we're waiting. Do
* not set RTS here - we want to make sure we catch
* the data from the modem.
*/
if (port->tty->termios->c_cflag & CBAUD)
uart_set_mctrl(uport, TIOCM_DTR);
/*
* and wait for the carrier to indicate that the
* modem is ready for us.
*/
spin_lock_irq(&uport->lock);
uport->ops->enable_ms(uport);
mctrl = uport->ops->get_mctrl(uport);
spin_unlock_irq(&uport->lock);
if (mctrl & TIOCM_CAR)
break;
mutex_unlock(&port->mutex);
schedule();
mutex_lock(&port->mutex);
if (signal_pending(current))
break;
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&port->open_wait, &wait);
port->count++;
port->blocked_open--;
if (signal_pending(current))
return -ERESTARTSYS;
if (!port->tty || tty_hung_up_p(filp))
return -EAGAIN;
int mctrl;
spin_lock_irq(&uport->lock);
uport->ops->enable_ms(uport);
mctrl = uport->ops->get_mctrl(uport);
spin_unlock_irq(&uport->lock);
if (mctrl & TIOCM_CAR)
return 1;
return 0;
}
static void uart_dtr_rts(struct tty_port *port, int onoff)
{
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport = state->uart_port;
if (onoff) {
uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
/*
* If this is the first open to succeed,
* adjust things to suit.
*/
if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags))
uart_update_termios(port->tty, state);
}
else
uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
}
static struct uart_state *uart_get(struct uart_driver *drv, int line)
{
struct uart_state *state;
@ -1611,7 +1591,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
struct tty_port *port;
int retval, line = tty->index;
BUG_ON(!kernel_locked());
BUG_ON(!tty_locked());
pr_debug("uart_open(%d) called\n", line);
/*
@ -1668,23 +1648,14 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
/*
* Start up the serial port.
*/
retval = uart_startup(state, 0);
retval = uart_startup(tty, state, 0);
/*
* If we succeeded, wait until the port is ready.
*/
if (retval == 0)
retval = uart_block_til_ready(filp, state);
mutex_unlock(&port->mutex);
/*
* If this is the first open to succeed, adjust things to suit.
*/
if (retval == 0 && !(port->flags & ASYNC_NORMAL_ACTIVE)) {
set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
uart_update_termios(state);
}
if (retval == 0)
retval = tty_port_block_til_ready(port, tty, filp);
fail:
return retval;
@ -2010,9 +1981,13 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
struct tty_port *port = &state->port;
struct device *tty_dev;
struct uart_match match = {uport, drv};
struct tty_struct *tty;
mutex_lock(&port->mutex);
/* Must be inside the mutex lock until we convert to tty_port */
tty = port->tty;
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (device_may_wakeup(tty_dev)) {
enable_irq_wake(uport->irq);
@ -2105,9 +2080,12 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
ops->set_mctrl(uport, 0);
spin_unlock_irq(&uport->lock);
if (console_suspend_enabled || !uart_console(uport)) {
/* Protected by port mutex for now */
struct tty_struct *tty = port->tty;
ret = ops->startup(uport);
if (ret == 0) {
uart_change_speed(state, NULL);
if (tty)
uart_change_speed(tty, state, NULL);
spin_lock_irq(&uport->lock);
ops->set_mctrl(uport, uport->mctrl);
ops->start_tx(uport);
@ -2119,7 +2097,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
* Clear the "initialized" flag so we won't try
* to call the low level drivers shutdown method.
*/
uart_shutdown(state);
uart_shutdown(tty, state);
}
}
@ -2312,6 +2290,11 @@ static const struct tty_operations uart_ops = {
#endif
};
static const struct tty_port_operations uart_port_ops = {
.carrier_raised = uart_carrier_raised,
.dtr_rts = uart_dtr_rts,
};
/**
* uart_register_driver - register a driver with the uart core layer
* @drv: low level driver structure
@ -2368,6 +2351,7 @@ int uart_register_driver(struct uart_driver *drv)
struct tty_port *port = &state->port;
tty_port_init(port);
port->ops = &uart_port_ops;
port->close_delay = 500; /* .5 seconds */
port->closing_wait = 30000; /* 30 seconds */
tasklet_init(&state->tlet, uart_tasklet_action,

View file

@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port)
return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
}
}
#elif defined(CONFIG_ARCH_SH7372)
static int scif_txfill(struct uart_port *port)
{
if (port->type == PORT_SCIFA)
return sci_in(port, SCFDR) >> 8;
else
return sci_in(port, SCTFDR);
}
static int scif_txroom(struct uart_port *port)
{
return port->fifosize - scif_txfill(port);
}
static int scif_rxfill(struct uart_port *port)
{
if (port->type == PORT_SCIFA)
return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
else
return sci_in(port, SCRFDR);
}
#else
static int scif_txfill(struct uart_port *port)
{
@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
u16 ssr = sci_in(port, SCxSR);
/* Disable future Rx interrupts */
if (port->type == PORT_SCIFA) {
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
disable_irq_nosync(irq);
scr |= 0x4000;
} else {
@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg)
if (!uart_circ_empty(xmit)) {
schedule_work(&s->work_tx);
} else if (port->type == PORT_SCIFA) {
} else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
u16 ctrl = sci_in(port, SCSCR);
sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
}
@ -1184,7 +1205,7 @@ static void sci_start_tx(struct uart_port *port)
unsigned short ctrl;
#ifdef CONFIG_SERIAL_SH_SCI_DMA
if (port->type == PORT_SCIFA) {
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
u16 new, scr = sci_in(port, SCSCR);
if (s->chan_tx)
new = scr | 0x8000;
@ -1197,7 +1218,7 @@ static void sci_start_tx(struct uart_port *port)
s->cookie_tx < 0)
schedule_work(&s->work_tx);
#endif
if (!s->chan_tx || port->type == PORT_SCIFA) {
if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
@ -1210,7 +1231,7 @@ static void sci_stop_tx(struct uart_port *port)
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
if (port->type == PORT_SCIFA)
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x8000;
ctrl &= ~SCI_CTRL_FLAGS_TIE;
sci_out(port, SCSCR, ctrl);
@ -1222,7 +1243,7 @@ static void sci_start_rx(struct uart_port *port)
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
ctrl |= sci_in(port, SCSCR);
if (port->type == PORT_SCIFA)
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x4000;
sci_out(port, SCSCR, ctrl);
}
@ -1233,7 +1254,7 @@ static void sci_stop_rx(struct uart_port *port)
/* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
if (port->type == PORT_SCIFA)
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x4000;
ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
sci_out(port, SCSCR, ctrl);
@ -1271,7 +1292,7 @@ static void rx_timer_fn(unsigned long arg)
struct uart_port *port = &s->port;
u16 scr = sci_in(port, SCSCR);
if (port->type == PORT_SCIFA) {
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
scr &= ~0x4000;
enable_irq(s->irqs[1]);
}
@ -1524,6 +1545,8 @@ static const char *sci_type(struct uart_port *port)
return "scif";
case PORT_SCIFA:
return "scifa";
case PORT_SCIFB:
return "scifb";
}
return NULL;
@ -1612,6 +1635,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
port->line = index;
switch (p->type) {
case PORT_SCIFB:
port->fifosize = 256;
break;
case PORT_SCIFA:
port->fifosize = 64;
break;

View file

@ -322,7 +322,7 @@
#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
static inline unsigned int sci_##name##_in(struct uart_port *port) \
{ \
if (port->type == PORT_SCIF) { \
if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
SCI_IN(scif_size, scif_offset) \
} else { /* PORT_SCI or PORT_SCIFA */ \
SCI_IN(sci_size, sci_offset); \
@ -330,7 +330,7 @@
} \
static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
{ \
if (port->type == PORT_SCIF) { \
if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
SCI_OUT(scif_size, scif_offset, value) \
} else { /* PORT_SCI or PORT_SCIFA */ \
SCI_OUT(sci_size, sci_offset, value); \
@ -384,8 +384,12 @@
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
defined(CONFIG_ARCH_SH7377)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#elif defined(CONFIG_ARCH_SH7372)
#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \
CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#else
@ -422,8 +426,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372)
defined(CONFIG_ARCH_SH7377)
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
@ -436,6 +439,20 @@ SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
SCIF_FNS(SCLSR, 0x00, 0)
#elif defined(CONFIG_ARCH_SH7372)
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
SCIF_FNS(SCSCR, 0x08, 16)
SCIF_FNS(SCTDSR, 0x0c, 16)
SCIF_FNS(SCFER, 0x10, 16)
SCIF_FNS(SCxSR, 0x14, 16)
SCIF_FNS(SCFCR, 0x18, 16)
SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCTFDR, 0x38, 16)
SCIF_FNS(SCRFDR, 0x3c, 16)
SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
SCIF_FNS(SCLSR, 0x00, 0)
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
defined(CONFIG_CPU_SUBTYPE_SH7724)
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)

View file

@ -519,7 +519,7 @@ static struct console sunhv_console = {
.data = &sunhv_reg,
};
static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match)
static int __devinit hv_probe(struct platform_device *op, const struct of_device_id *match)
{
struct uart_port *port;
unsigned long minor;
@ -598,7 +598,7 @@ out_free_port:
return err;
}
static int __devexit hv_remove(struct of_device *dev)
static int __devexit hv_remove(struct platform_device *dev)
{
struct uart_port *port = dev_get_drvdata(&dev->dev);

View file

@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options)
printk("Console: ttyS%d (SAB82532)\n",
(sunsab_reg.minor - 64) + con->index);
sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node);
sunserial_console_termios(con, up->port.dev->of_node);
switch (con->cflag & CBAUD) {
case B150: baud = 150; break;
@ -954,7 +954,7 @@ static inline struct console *SUNSAB_CONSOLE(void)
#endif
static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
struct of_device *op,
struct platform_device *op,
unsigned long offset,
int line)
{
@ -1006,7 +1006,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
return 0;
}
static int __devinit sab_probe(struct of_device *op, const struct of_device_id *match)
static int __devinit sab_probe(struct platform_device *op, const struct of_device_id *match)
{
static int inst;
struct uart_sunsab_port *up;
@ -1062,7 +1062,7 @@ out:
return err;
}
static int __devexit sab_remove(struct of_device *op)
static int __devexit sab_remove(struct platform_device *op)
{
struct uart_sunsab_port *up = dev_get_drvdata(&op->dev);

View file

@ -1200,7 +1200,7 @@ static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up)
return -ENODEV;
printk("%s: %s port at %llx, irq %u\n",
to_of_device(up->port.dev)->dev.of_node->full_name,
up->port.dev->of_node->full_name,
(up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
(unsigned long long) up->port.mapbase,
up->port.irq);
@ -1352,7 +1352,7 @@ static int __init sunsu_console_setup(struct console *co, char *options)
spin_lock_init(&port->lock);
/* Get firmware console settings. */
sunserial_console_termios(co, to_of_device(port->dev)->dev.of_node);
sunserial_console_termios(co, port->dev->of_node);
memset(&termios, 0, sizeof(struct ktermios));
termios.c_cflag = co->cflag;
@ -1406,7 +1406,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp)
return SU_PORT_PORT;
}
static int __devinit su_probe(struct of_device *op, const struct of_device_id *match)
static int __devinit su_probe(struct platform_device *op, const struct of_device_id *match)
{
static int inst;
struct device_node *dp = op->dev.of_node;
@ -1497,7 +1497,7 @@ out_unmap:
return err;
}
static int __devexit su_remove(struct of_device *op)
static int __devexit su_remove(struct platform_device *op)
{
struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
bool kbdms = false;

View file

@ -1230,7 +1230,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
(sunzilog_reg.minor - 64) + con->index, con->index);
/* Get firmware console settings. */
sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node);
sunserial_console_termios(con, up->port.dev->of_node);
/* Firmware console speed is limited to 150-->38400 baud so
* this hackish cflag thing is OK.
@ -1399,7 +1399,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
static int zilog_irq = -1;
static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match)
static int __devinit zs_probe(struct platform_device *op, const struct of_device_id *match)
{
static int kbm_inst, uart_inst;
int inst;
@ -1516,7 +1516,7 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
uart_remove_one_port(&sunzilog_reg, &up->port);
}
static int __devexit zs_remove(struct of_device *op)
static int __devexit zs_remove(struct platform_device *op)
{
struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev);
struct zilog_layout __iomem *regs;

View file

@ -423,7 +423,7 @@ static struct uart_driver timbuart_driver = {
.nr = 1
};
static int timbuart_probe(struct platform_device *dev)
static int __devinit timbuart_probe(struct platform_device *dev)
{
int err, irq;
struct timbuart_port *uart;
@ -489,7 +489,7 @@ err_mem:
return err;
}
static int timbuart_remove(struct platform_device *dev)
static int __devexit timbuart_remove(struct platform_device *dev)
{
struct timbuart_port *uart = platform_get_drvdata(dev);
@ -507,7 +507,7 @@ static struct platform_driver timbuart_platform_driver = {
.owner = THIS_MODULE,
},
.probe = timbuart_probe,
.remove = timbuart_remove,
.remove = __devexit_p(timbuart_remove),
};
/*--------------------------------------------------------------------------*/

View file

@ -584,7 +584,7 @@ static struct platform_driver ulite_platform_driver = {
*/
#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
static int __devinit
ulite_of_probe(struct of_device *op, const struct of_device_id *match)
ulite_of_probe(struct platform_device *op, const struct of_device_id *match)
{
struct resource res;
const unsigned int *id;
@ -605,7 +605,7 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match)
return ulite_assign(&op->dev, id ? *id : -1, res.start, irq);
}
static int __devexit ulite_of_remove(struct of_device *op)
static int __devexit ulite_of_remove(struct platform_device *op)
{
return ulite_release(&op->dev);
}

View file

@ -1194,7 +1194,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context)
release_firmware(fw);
}
static int ucc_uart_probe(struct of_device *ofdev,
static int ucc_uart_probe(struct platform_device *ofdev,
const struct of_device_id *match)
{
struct device_node *np = ofdev->dev.of_node;
@ -1462,7 +1462,7 @@ static int ucc_uart_probe(struct of_device *ofdev,
return 0;
}
static int ucc_uart_remove(struct of_device *ofdev)
static int ucc_uart_remove(struct platform_device *ofdev)
{
struct uart_qe_port *qe_port = dev_get_drvdata(&ofdev->dev);