mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
This commit is contained in:
commit
300a103d15
3413 changed files with 162402 additions and 388470 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
344
drivers/serial/max3107-aava.c
Normal file
344
drivers/serial/max3107-aava.c
Normal 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
1197
drivers/serial/max3107.c
Normal file
File diff suppressed because it is too large
Load diff
441
drivers/serial/max3107.h
Normal file
441
drivers/serial/max3107.h
Normal 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 */
|
||||
|
|
@ -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
1498
drivers/serial/mfd.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
844
drivers/serial/mrst_max3110.c
Normal file
844
drivers/serial/mrst_max3110.c
Normal 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");
|
||||
59
drivers/serial/mrst_max3110.h
Normal file
59
drivers/serial/mrst_max3110.h
Normal 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
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue