Commit 5983faf9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (65 commits)
  tty: serial: imx: move del_timer_sync() to avoid potential deadlock
  imx: add polled io uart methods
  imx: Add save/restore functions for UART control regs
  serial/imx: let probing fail for the dt case without a valid alias
  serial/imx: propagate error from of_alias_get_id instead of using -ENODEV
  tty: serial: imx: Allow UART to be a source for wakeup
  serial: driver for m32 arch should not have DEC alpha errata
  serial/documentation: fix documented name of DCD cpp symbol
  atmel_serial: fix spinlock lockup in RS485 code
  tty: Fix memory leak in virtual console when enable unicode translation
  serial: use DIV_ROUND_CLOSEST instead of open coding it
  serial: add support for 400 and 800 v3 series Titan cards
  serial: bfin-uart: Remove ASYNC_CTS_FLOW flag for hardware automatic CTS.
  serial: bfin-uart: Enable hardware automatic CTS only when CTS pin is available.
  serial: make FSL errata depend on 8250_CONSOLE, not just 8250
  serial: add irq handler for Freescale 16550 errata.
  serial: manually inline serial8250_handle_port
  serial: make 8250 timeout use the specified IRQ handler
  serial: export the key functions for an 8250 IRQ handler
  serial: clean up parameter passing for 8250 Rx IRQ handling
  ...
parents 21a2cb56 995234da
...@@ -101,7 +101,7 @@ hardware. ...@@ -101,7 +101,7 @@ hardware.
Returns the current state of modem control inputs. The state Returns the current state of modem control inputs. The state
of the outputs should not be returned, since the core keeps of the outputs should not be returned, since the core keeps
track of their state. The state information should include: track of their state. The state information should include:
- TIOCM_DCD state of DCD signal - TIOCM_CAR state of DCD signal
- TIOCM_CTS state of CTS signal - TIOCM_CTS state of CTS signal
- TIOCM_DSR state of DSR signal - TIOCM_DSR state of DSR signal
- TIOCM_RI state of RI signal - TIOCM_RI state of RI signal
......
...@@ -441,6 +441,9 @@ static void __init fixup_port_irq(int index, ...@@ -441,6 +441,9 @@ static void __init fixup_port_irq(int index,
return; return;
port->irq = virq; port->irq = virq;
if (of_device_is_compatible(np, "fsl,ns16550"))
port->handle_irq = fsl8250_handle_irq;
} }
static void __init fixup_port_pio(int index, static void __init fixup_port_pio(int index,
......
...@@ -67,7 +67,7 @@ extern struct console early_mrst_console; ...@@ -67,7 +67,7 @@ extern struct console early_mrst_console;
extern void mrst_early_console_init(void); extern void mrst_early_console_init(void);
extern struct console early_hsu_console; extern struct console early_hsu_console;
extern void hsu_early_console_init(void); extern void hsu_early_console_init(const char *);
extern void intel_scu_devices_create(void); extern void intel_scu_devices_create(void);
extern void intel_scu_devices_destroy(void); extern void intel_scu_devices_destroy(void);
......
...@@ -247,7 +247,7 @@ static int __init setup_early_printk(char *buf) ...@@ -247,7 +247,7 @@ static int __init setup_early_printk(char *buf)
} }
if (!strncmp(buf, "hsu", 3)) { if (!strncmp(buf, "hsu", 3)) {
hsu_early_console_init(); hsu_early_console_init(buf + 3);
early_console_register(&early_hsu_console, keep); early_console_register(&early_hsu_console, keep);
} }
#endif #endif
......
...@@ -245,16 +245,24 @@ struct console early_mrst_console = { ...@@ -245,16 +245,24 @@ struct console early_mrst_console = {
* Following is the early console based on Medfield HSU (High * Following is the early console based on Medfield HSU (High
* Speed UART) device. * Speed UART) device.
*/ */
#define HSU_PORT2_PADDR 0xffa28180 #define HSU_PORT_BASE 0xffa28080
static void __iomem *phsu; static void __iomem *phsu;
void hsu_early_console_init(void) void hsu_early_console_init(const char *s)
{ {
unsigned long paddr, port = 0;
u8 lcr; u8 lcr;
phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, /*
HSU_PORT2_PADDR); * Select the early HSU console port if specified by user in the
* kernel command line.
*/
if (*s && !kstrtoul(s, 10, &port))
port = clamp_val(port, 0, 2);
paddr = HSU_PORT_BASE + port * 0x80;
phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr);
/* Disable FIFO */ /* Disable FIFO */
writeb(0x0, phsu + UART_FCR); writeb(0x0, phsu + UART_FCR);
......
...@@ -420,18 +420,7 @@ static struct platform_driver axdrv = { ...@@ -420,18 +420,7 @@ static struct platform_driver axdrv = {
.resume = parport_ax88796_resume, .resume = parport_ax88796_resume,
}; };
static int __init parport_ax88796_init(void) module_platform_driver(axdrv);
{
return platform_driver_register(&axdrv);
}
static void __exit parport_ax88796_exit(void)
{
platform_driver_unregister(&axdrv);
}
module_init(parport_ax88796_init)
module_exit(parport_ax88796_exit)
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_DESCRIPTION("AX88796 Parport parallel port driver"); MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
......
...@@ -391,21 +391,10 @@ static struct platform_driver bpp_sbus_driver = { ...@@ -391,21 +391,10 @@ static struct platform_driver bpp_sbus_driver = {
.remove = __devexit_p(bpp_remove), .remove = __devexit_p(bpp_remove),
}; };
static int __init parport_sunbpp_init(void) module_platform_driver(bpp_sbus_driver);
{
return platform_driver_register(&bpp_sbus_driver);
}
static void __exit parport_sunbpp_exit(void)
{
platform_driver_unregister(&bpp_sbus_driver);
}
MODULE_AUTHOR("Derrick J Brashear"); MODULE_AUTHOR("Derrick J Brashear");
MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
MODULE_VERSION("2.0"); MODULE_VERSION("2.0");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_init(parport_sunbpp_init)
module_exit(parport_sunbpp_exit)
...@@ -417,7 +417,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) ...@@ -417,7 +417,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
__FILE__,__LINE__,tbuf,tbuf->count); __FILE__,__LINE__,tbuf,tbuf->count);
/* Send the next block of data to device */ /* Send the next block of data to device */
tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
actual = tty->ops->write(tty, tbuf->buf, tbuf->count); actual = tty->ops->write(tty, tbuf->buf, tbuf->count);
/* rollback was possible and has been done */ /* rollback was possible and has been done */
...@@ -459,7 +459,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) ...@@ -459,7 +459,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
} }
if (!tbuf) if (!tbuf)
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
/* Clear the re-entry flag */ /* Clear the re-entry flag */
spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
...@@ -491,7 +491,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) ...@@ -491,7 +491,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
return; return;
if (tty != n_hdlc->tty) { if (tty != n_hdlc->tty) {
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
return; return;
} }
......
...@@ -446,19 +446,8 @@ static inline void legacy_pty_init(void) { } ...@@ -446,19 +446,8 @@ static inline void legacy_pty_init(void) { }
int pty_limit = NR_UNIX98_PTY_DEFAULT; int pty_limit = NR_UNIX98_PTY_DEFAULT;
static int pty_limit_min; static int pty_limit_min;
static int pty_limit_max = NR_UNIX98_PTY_MAX; static int pty_limit_max = NR_UNIX98_PTY_MAX;
static int tty_count;
static int pty_count; static int pty_count;
static inline void pty_inc_count(void)
{
pty_count = (++tty_count) / 2;
}
static inline void pty_dec_count(void)
{
pty_count = (--tty_count) / 2;
}
static struct cdev ptmx_cdev; static struct cdev ptmx_cdev;
static struct ctl_table pty_table[] = { static struct ctl_table pty_table[] = {
...@@ -600,8 +589,7 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) ...@@ -600,8 +589,7 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
*/ */
tty_driver_kref_get(driver); tty_driver_kref_get(driver);
tty->count++; tty->count++;
pty_inc_count(); /* tty */ pty_count++;
pty_inc_count(); /* tty->link */
return 0; return 0;
err_free_mem: err_free_mem:
deinitialize_tty_struct(o_tty); deinitialize_tty_struct(o_tty);
...@@ -613,15 +601,19 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) ...@@ -613,15 +601,19 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENOMEM; return -ENOMEM;
} }
static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
{
pty_count--;
}
static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
{ {
pty_dec_count();
} }
static const struct tty_operations ptm_unix98_ops = { static const struct tty_operations ptm_unix98_ops = {
.lookup = ptm_unix98_lookup, .lookup = ptm_unix98_lookup,
.install = pty_unix98_install, .install = pty_unix98_install,
.remove = pty_unix98_remove, .remove = ptm_unix98_remove,
.open = pty_open, .open = pty_open,
.close = pty_close, .close = pty_close,
.write = pty_write, .write = pty_write,
...@@ -638,7 +630,7 @@ static const struct tty_operations ptm_unix98_ops = { ...@@ -638,7 +630,7 @@ static const struct tty_operations ptm_unix98_ops = {
static const struct tty_operations pty_unix98_ops = { static const struct tty_operations pty_unix98_ops = {
.lookup = pts_unix98_lookup, .lookup = pts_unix98_lookup,
.install = pty_unix98_install, .install = pty_unix98_install,
.remove = pty_unix98_remove, .remove = pts_unix98_remove,
.open = pty_open, .open = pty_open,
.close = pty_close, .close = pty_close,
.write = pty_write, .write = pty_write,
......
...@@ -129,32 +129,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX]; ...@@ -129,32 +129,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX];
static unsigned int probe_rsa_count; static unsigned int probe_rsa_count;
#endif /* CONFIG_SERIAL_8250_RSA */ #endif /* CONFIG_SERIAL_8250_RSA */
struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
unsigned short capabilities; /* port capabilities */
unsigned short bugs; /* port bugs */
unsigned int tx_loadsz; /* transmit fifo load size */
unsigned char acr;
unsigned char ier;
unsigned char lcr;
unsigned char mcr;
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
unsigned char cur_iotype; /* Running I/O type */
/*
* Some bits in registers are cleared on a read, so they must
* be saved whenever the register is read but the bits will not
* be immediately processed.
*/
#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
unsigned char lsr_saved_flags;
#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
unsigned char msr_saved_flags;
};
struct irq_info { struct irq_info {
struct hlist_node node; struct hlist_node node;
int irq; int irq;
...@@ -1326,8 +1300,6 @@ static void serial8250_stop_tx(struct uart_port *port) ...@@ -1326,8 +1300,6 @@ static void serial8250_stop_tx(struct uart_port *port)
} }
} }
static void transmit_chars(struct uart_8250_port *up);
static void serial8250_start_tx(struct uart_port *port) static void serial8250_start_tx(struct uart_port *port)
{ {
struct uart_8250_port *up = struct uart_8250_port *up =
...@@ -1344,7 +1316,7 @@ static void serial8250_start_tx(struct uart_port *port) ...@@ -1344,7 +1316,7 @@ static void serial8250_start_tx(struct uart_port *port)
if ((up->port.type == PORT_RM9000) ? if ((up->port.type == PORT_RM9000) ?
(lsr & UART_LSR_THRE) : (lsr & UART_LSR_THRE) :
(lsr & UART_LSR_TEMT)) (lsr & UART_LSR_TEMT))
transmit_chars(up); serial8250_tx_chars(up);
} }
} }
...@@ -1401,11 +1373,16 @@ static void clear_rx_fifo(struct uart_8250_port *up) ...@@ -1401,11 +1373,16 @@ static void clear_rx_fifo(struct uart_8250_port *up)
} while (1); } while (1);
} }
static void /*
receive_chars(struct uart_8250_port *up, unsigned int *status) * serial8250_rx_chars: processes according to the passed in LSR
* value, and returns the remaining LSR bits not handled
* by this Rx routine.
*/
unsigned char
serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
{ {
struct tty_struct *tty = up->port.state->port.tty; struct tty_struct *tty = up->port.state->port.tty;
unsigned char ch, lsr = *status; unsigned char ch;
int max_count = 256; int max_count = 256;
char flag; char flag;
...@@ -1481,10 +1458,11 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) ...@@ -1481,10 +1458,11 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
spin_unlock(&up->port.lock); spin_unlock(&up->port.lock);
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
spin_lock(&up->port.lock); spin_lock(&up->port.lock);
*status = lsr; return lsr;
} }
EXPORT_SYMBOL_GPL(serial8250_rx_chars);
static void transmit_chars(struct uart_8250_port *up) void serial8250_tx_chars(struct uart_8250_port *up)
{ {
struct circ_buf *xmit = &up->port.state->xmit; struct circ_buf *xmit = &up->port.state->xmit;
int count; int count;
...@@ -1521,8 +1499,9 @@ static void transmit_chars(struct uart_8250_port *up) ...@@ -1521,8 +1499,9 @@ static void transmit_chars(struct uart_8250_port *up)
if (uart_circ_empty(xmit)) if (uart_circ_empty(xmit))
__stop_tx(up); __stop_tx(up);
} }
EXPORT_SYMBOL_GPL(serial8250_tx_chars);
static unsigned int check_modem_status(struct uart_8250_port *up) unsigned int serial8250_modem_status(struct uart_8250_port *up)
{ {
unsigned int status = serial_in(up, UART_MSR); unsigned int status = serial_in(up, UART_MSR);
...@@ -1544,14 +1523,20 @@ static unsigned int check_modem_status(struct uart_8250_port *up) ...@@ -1544,14 +1523,20 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
return status; return status;
} }
EXPORT_SYMBOL_GPL(serial8250_modem_status);
/* /*
* This handles the interrupt from one port. * This handles the interrupt from one port.
*/ */
static void serial8250_handle_port(struct uart_8250_port *up) int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
{ {
unsigned int status; unsigned char status;
unsigned long flags; unsigned long flags;
struct uart_8250_port *up =
container_of(port, struct uart_8250_port, port);
if (iir & UART_IIR_NO_INT)
return 0;
spin_lock_irqsave(&up->port.lock, flags); spin_lock_irqsave(&up->port.lock, flags);
...@@ -1560,25 +1545,13 @@ static void serial8250_handle_port(struct uart_8250_port *up) ...@@ -1560,25 +1545,13 @@ static void serial8250_handle_port(struct uart_8250_port *up)
DEBUG_INTR("status = %x...", status); DEBUG_INTR("status = %x...", status);
if (status & (UART_LSR_DR | UART_LSR_BI)) if (status & (UART_LSR_DR | UART_LSR_BI))
receive_chars(up, &status); status = serial8250_rx_chars(up, status);
check_modem_status(up); serial8250_modem_status(up);
if (status & UART_LSR_THRE) if (status & UART_LSR_THRE)
transmit_chars(up); serial8250_tx_chars(up);
spin_unlock_irqrestore(&up->port.lock, flags); spin_unlock_irqrestore(&up->port.lock, flags);
}
int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
{
struct uart_8250_port *up =
container_of(port, struct uart_8250_port, port);
if (!(iir & UART_IIR_NO_INT)) {
serial8250_handle_port(up);
return 1; return 1;
}
return 0;
} }
EXPORT_SYMBOL_GPL(serial8250_handle_irq); EXPORT_SYMBOL_GPL(serial8250_handle_irq);
...@@ -1619,11 +1592,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) ...@@ -1619,11 +1592,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
do { do {
struct uart_8250_port *up; struct uart_8250_port *up;
struct uart_port *port; struct uart_port *port;
bool skip;
up = list_entry(l, struct uart_8250_port, list); up = list_entry(l, struct uart_8250_port, list);
port = &up->port; port = &up->port;
skip = pass_counter && up->port.flags & UPF_IIR_ONCE;
if (port->handle_irq(port)) { if (!skip && port->handle_irq(port)) {
handled = 1; handled = 1;
end = NULL; end = NULL;
} else if (end == NULL) } else if (end == NULL)
...@@ -1758,11 +1733,8 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) ...@@ -1758,11 +1733,8 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
static void serial8250_timeout(unsigned long data) static void serial8250_timeout(unsigned long data)
{ {
struct uart_8250_port *up = (struct uart_8250_port *)data; struct uart_8250_port *up = (struct uart_8250_port *)data;
unsigned int iir;
iir = serial_in(up, UART_IIR); up->port.handle_irq(&up->port);
if (!(iir & UART_IIR_NO_INT))
serial8250_handle_port(up);
mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
} }
...@@ -1801,7 +1773,7 @@ static void serial8250_backup_timeout(unsigned long data) ...@@ -1801,7 +1773,7 @@ static void serial8250_backup_timeout(unsigned long data)
} }
if (!(iir & UART_IIR_NO_INT)) if (!(iir & UART_IIR_NO_INT))
transmit_chars(up); serial8250_tx_chars(up);
if (is_real_interrupt(up->port.irq)) if (is_real_interrupt(up->port.irq))
serial_out(up, UART_IER, ier); serial_out(up, UART_IER, ier);
...@@ -1835,7 +1807,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) ...@@ -1835,7 +1807,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
unsigned int status; unsigned int status;
unsigned int ret; unsigned int ret;
status = check_modem_status(up); status = serial8250_modem_status(up);
ret = 0; ret = 0;
if (status & UART_MSR_DCD) if (status & UART_MSR_DCD)
...@@ -2000,7 +1972,7 @@ static int serial8250_startup(struct uart_port *port) ...@@ -2000,7 +1972,7 @@ static int serial8250_startup(struct uart_port *port)
serial_outp(up, UART_IER, 0); serial_outp(up, UART_IER, 0);
serial_outp(up, UART_LCR, 0); serial_outp(up, UART_LCR, 0);
serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
serial_outp(up, UART_LCR, 0xBF); serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_outp(up, UART_EFR, UART_EFR_ECB); serial_outp(up, UART_EFR, UART_EFR_ECB);
serial_outp(up, UART_LCR, 0); serial_outp(up, UART_LCR, 0);
} }
...@@ -2848,7 +2820,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) ...@@ -2848,7 +2820,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
local_irq_save(flags); local_irq_save(flags);
if (up->port.sysrq) { if (up->port.sysrq) {
/* serial8250_handle_port() already took the lock */ /* serial8250_handle_irq() already took the lock */
locked = 0; locked = 0;
} else if (oops_in_progress) { } else if (oops_in_progress) {
locked = spin_trylock(&up->port.lock); locked = spin_trylock(&up->port.lock);
...@@ -2882,7 +2854,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) ...@@ -2882,7 +2854,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
* while processing with interrupts off. * while processing with interrupts off.
*/ */
if (up->msr_saved_flags) if (up->msr_saved_flags)
check_modem_status(up); serial8250_modem_status(up);
if (locked) if (locked)
spin_unlock(&up->port.lock); spin_unlock(&up->port.lock);
......
...@@ -13,6 +13,32 @@ ...@@ -13,6 +13,32 @@
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
unsigned short capabilities; /* port capabilities */
unsigned short bugs; /* port bugs */
unsigned int tx_loadsz; /* transmit fifo load size */
unsigned char acr;
unsigned char ier;
unsigned char lcr;
unsigned char mcr;
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
unsigned char cur_iotype; /* Running I/O type */
/*
* Some bits in registers are cleared on a read, so they must
* be saved whenever the register is read but the bits will not
* be immediately processed.
*/
#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
unsigned char lsr_saved_flags;
#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
unsigned char msr_saved_flags;
};
struct old_serial_port { struct old_serial_port {
unsigned int uart; unsigned int uart;
unsigned int baud_base; unsigned int baud_base;
......
...@@ -177,17 +177,7 @@ static struct platform_driver dw8250_platform_driver = { ...@@ -177,17 +177,7 @@ static struct platform_driver dw8250_platform_driver = {
.remove = __devexit_p(dw8250_remove), .remove = __devexit_p(dw8250_remove),
}; };
static int __init dw8250_init(void) module_platform_driver(dw8250_platform_driver);
{
return platform_driver_register(&dw8250_platform_driver);
}
module_init(dw8250_init);
static void __exit dw8250_exit(void)
{
platform_driver_unregister(&dw8250_platform_driver);
}
module_exit(dw8250_exit);
MODULE_AUTHOR("Jamie Iles"); MODULE_AUTHOR("Jamie Iles");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
#include "8250.h"
/*
* Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This isn't a full driver; it just provides an alternate IRQ
* handler to deal with an errata. Everything else is just
* using the bog standard 8250 support.
*
* We follow code flow of serial8250_default_handle_irq() but add
* a check for a break and insert a dummy read on the Rx for the
* immediately following IRQ event.
*
* We re-use the already existing "bug handling" lsr_saved_flags
* field to carry the "what we just did" information from the one
* IRQ event to the next one.
*/
int fsl8250_handle_irq(struct uart_port *port)
{
unsigned char lsr, orig_lsr;
unsigned long flags;
unsigned int iir;
struct uart_8250_port *up =
container_of(port, struct uart_8250_port, port);
spin_lock_irqsave(&up->port.lock, flags);
iir = port->serial_in(port, UART_IIR);
if (iir & UART_IIR_NO_INT) {
spin_unlock_irqrestore(&up->port.lock, flags);
return 0;
}
/* This is the WAR; if last event was BRK, then read and return */
if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
up->lsr_saved_flags &= ~UART_LSR_BI;
port->serial_in(port, UART_RX);
spin_unlock_irqrestore(&up->port.lock, flags);
return 1;
}
lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
if (lsr & (UART_LSR_DR | UART_LSR_BI))
lsr = serial8250_rx_chars(up, lsr);
serial8250_modem_status(up);
if (lsr & UART_LSR_THRE)
serial8250_tx_chars(up);
up->lsr_saved_flags = orig_lsr;
spin_unlock_irqrestore(&up->port.lock, flags);
return 1;
}
...@@ -1092,6 +1092,14 @@ static int skip_tx_en_setup(struct serial_private *priv, ...@@ -1092,6 +1092,14 @@ static int skip_tx_en_setup(struct serial_private *priv,
return pci_default_setup(priv, board, port, idx); return pci_default_setup(priv, board, port, idx);
} }
static int kt_serial_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_port *port, int idx)
{
port->flags |= UPF_IIR_ONCE;
return skip_tx_en_setup(priv, board, port, idx);
}
static int pci_eg20t_init(struct pci_dev *dev) static int pci_eg20t_init(struct pci_dev *dev)
{ {
#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
...@@ -1110,7 +1118,18 @@ pci_xr17c154_setup(struct serial_private *priv, ...@@ -1110,7 +1118,18 @@ pci_xr17c154_setup(struct serial_private *priv,
return pci_default_setup(priv, board, port, idx); return pci_default_setup(priv, board, port, idx);
} }
/* This should be in linux/pci_ids.h */ static int try_enable_msi(struct pci_dev *dev)
{
/* use msi if available, but fallback to legacy otherwise */
pci_enable_msi(dev);
return 0;
}
static void disable_msi(struct pci_dev *dev)
{
pci_disable_msi(dev);
}
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_VENDOR_ID_SBSMODULARIO 0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
#define PCI_DEVICE_ID_OCTPRO 0x0001 #define PCI_DEVICE_ID_OCTPRO 0x0001
...@@ -1133,9 +1152,14 @@ pci_xr17c154_setup(struct serial_private *priv, ...@@ -1133,9 +1152,14 @@ pci_xr17c154_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_TITAN_800E 0xA014 #define PCI_DEVICE_ID_TITAN_800E 0xA014
#define PCI_DEVICE_ID_TITAN_200EI 0xA016 #define PCI_DEVICE_ID_TITAN_200EI 0xA016
#define PCI_DEVICE_ID_TITAN_200EISI 0xA017 #define PCI_DEVICE_ID_TITAN_200EISI 0xA017
#define PCI_DEVICE_ID_TITAN_400V3 0xA310
#define PCI_DEVICE_ID_TITAN_410V3 0xA312
#define PCI_DEVICE_ID_TITAN_800V3 0xA314
#define PCI_DEVICE_ID_TITAN_800V3B 0xA315
#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
...@@ -1220,6 +1244,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { ...@@ -1220,6 +1244,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.setup = ce4100_serial_setup, .setup = ce4100_serial_setup,
}, },
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = try_enable_msi,
.setup = kt_serial_setup,
.exit = disable_msi,
},
/* /*
* ITE * ITE
*/ */
...@@ -3414,6 +3447,18 @@ static struct pci_device_id serial_pci_tbl[] = { ...@@ -3414,6 +3447,18 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_oxsemi_2_4000000 }, pbn_oxsemi_2_4000000 },
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_921600 },
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_921600 },
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_921600 },
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_921600 },
{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
......
...@@ -97,6 +97,11 @@ config SERIAL_8250_PNP ...@@ -97,6 +97,11 @@ config SERIAL_8250_PNP
This builds standard PNP serial support. You may be able to This builds standard PNP serial support. You may be able to
disable this feature if you only need legacy serial support. disable this feature if you only need legacy serial support.
config SERIAL_8250_FSL
bool
depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550
default PPC
config SERIAL_8250_HP300 config SERIAL_8250_HP300
tristate tristate
depends on SERIAL_8250 && HP300 depends on SERIAL_8250 && HP300
...@@ -535,6 +540,27 @@ config SERIAL_S5PV210 ...@@ -535,6 +540,27 @@ config SERIAL_S5PV210
help help
Serial port support for Samsung's S5P Family of SoC's Serial port support for Samsung's S5P Family of SoC's
config SERIAL_SIRFSOC
tristate "SiRF SoC Platform Serial port support"
depends on ARM && ARCH_PRIMA2
select SERIAL_CORE
help
Support for the on-chip UART on the CSR SiRFprimaII series,
providing /dev/ttySiRF0, 1 and 2 (note, some machines may not
provide all of these ports, depending on how the serial port
pins are configured).
config SERIAL_SIRFSOC_CONSOLE
bool "Support for console on SiRF SoC serial port"
depends on SERIAL_SIRFSOC=y
select SERIAL_CORE_CONSOLE
help
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttySiRFx". (Try "man bootparam" or see the documentation of
your boot loader about how to pass options to the kernel at
boot time.)
config SERIAL_MAX3100 config SERIAL_MAX3100
tristate "MAX3100 support" tristate "MAX3100 support"
...@@ -1324,7 +1350,7 @@ config SERIAL_OF_PLATFORM ...@@ -1324,7 +1350,7 @@ config SERIAL_OF_PLATFORM
config SERIAL_OMAP config SERIAL_OMAP
tristate "OMAP serial port support" tristate "OMAP serial port support"
depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4 depends on ARCH_OMAP2PLUS
select SERIAL_CORE select SERIAL_CORE
help help
If you have a machine based on an Texas Instruments OMAP CPU you If you have a machine based on an Texas Instruments OMAP CPU you
...@@ -1575,6 +1601,15 @@ config SERIAL_PCH_UART ...@@ -1575,6 +1601,15 @@ config SERIAL_PCH_UART
ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
config SERIAL_PCH_UART_CONSOLE
bool "Support for console on Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH"
depends on SERIAL_PCH_UART=y
select SERIAL_CORE_CONSOLE
help
Say Y here if you wish to use the PCH UART as the system console
(the system console is the device which receives all kernel messages and
warnings and which allows logins in single user mode).
config SERIAL_MSM_SMD config SERIAL_MSM_SMD
bool "Enable tty device interface for some SMD ports" bool "Enable tty device interface for some SMD ports"
default n default n
......
...@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
...@@ -94,3 +95,4 @@ obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o ...@@ -94,3 +95,4 @@ obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o
obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
...@@ -212,8 +212,9 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) ...@@ -212,8 +212,9 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
{ {
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
unsigned int mode; unsigned int mode;
unsigned long flags;
spin_lock(&port->lock); spin_lock_irqsave(&port->lock, flags);
/* Disable interrupts */ /* Disable interrupts */
UART_PUT_IDR(port, atmel_port->tx_done_mask); UART_PUT_IDR(port, atmel_port->tx_done_mask);
...@@ -244,7 +245,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) ...@@ -244,7 +245,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
/* Enable interrupts */ /* Enable interrupts */
UART_PUT_IER(port, atmel_port->tx_done_mask); UART_PUT_IER(port, atmel_port->tx_done_mask);
spin_unlock(&port->lock); spin_unlock_irqrestore(&port->lock, flags);
} }
...@@ -1256,12 +1257,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -1256,12 +1257,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
static void atmel_set_ldisc(struct uart_port *port, int new) static void atmel_set_ldisc(struct uart_port *port, int new)
{ {
int line = port->line; if (new == N_PPS) {
if (line >= port->state->port.tty->driver->num)
return;
if (port->state->port.tty->ldisc->ops->num == N_PPS) {
port->flags |= UPF_HARDPPS_CD; port->flags |= UPF_HARDPPS_CD;
atmel_enable_ms(port); atmel_enable_ms(port);
} else { } else {
......
...@@ -299,8 +299,13 @@ static int sport_startup(struct uart_port *port) ...@@ -299,8 +299,13 @@ static int sport_startup(struct uart_port *port)
dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n"); dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n");
} }
} }
if (up->rts_pin >= 0) if (up->rts_pin >= 0) {
if (gpio_request(up->rts_pin, DRV_NAME)) {
dev_info(port->dev, "fail to request RTS PIN at GPIO_%d\n", up->rts_pin);
up->rts_pin = -1;
} else
gpio_direction_output(up->rts_pin, 0); gpio_direction_output(up->rts_pin, 0);
}
#endif #endif
return 0; return 0;
...@@ -445,6 +450,8 @@ static void sport_shutdown(struct uart_port *port) ...@@ -445,6 +450,8 @@ static void sport_shutdown(struct uart_port *port)
#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
if (up->cts_pin >= 0) if (up->cts_pin >= 0)
free_irq(gpio_to_irq(up->cts_pin), up); free_irq(gpio_to_irq(up->cts_pin), up);
if (up->rts_pin >= 0)
gpio_free(up->rts_pin);
#endif #endif
} }
...@@ -803,17 +810,16 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) ...@@ -803,17 +810,16 @@ static int __devinit sport_uart_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IO, 0); res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (res == NULL) if (res == NULL)
sport->cts_pin = -1; sport->cts_pin = -1;
else else {
sport->cts_pin = res->start; sport->cts_pin = res->start;
sport->port.flags |= ASYNC_CTS_FLOW;
}
res = platform_get_resource(pdev, IORESOURCE_IO, 1); res = platform_get_resource(pdev, IORESOURCE_IO, 1);
if (res == NULL) if (res == NULL)
sport->rts_pin = -1; sport->rts_pin = -1;
else else
sport->rts_pin = res->start; sport->rts_pin = res->start;
if (sport->rts_pin >= 0)
gpio_request(sport->rts_pin, DRV_NAME);
#endif #endif
} }
...@@ -853,10 +859,6 @@ static int __devexit sport_uart_remove(struct platform_device *pdev) ...@@ -853,10 +859,6 @@ static int __devexit sport_uart_remove(struct platform_device *pdev)
if (sport) { if (sport) {
uart_remove_one_port(&sport_uart_reg, &sport->port); uart_remove_one_port(&sport_uart_reg, &sport->port);
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
if (sport->rts_pin >= 0)
gpio_free(sport->rts_pin);
#endif
iounmap(sport->port.membase); iounmap(sport->port.membase);
peripheral_free_list( peripheral_free_list(
(unsigned short *)pdev->dev.platform_data); (unsigned short *)pdev->dev.platform_data);
......
...@@ -45,11 +45,12 @@ ...@@ -45,11 +45,12 @@
#define SPORT_GET_RX32(sport) \ #define SPORT_GET_RX32(sport) \
({ \ ({ \
unsigned int __ret; \ unsigned int __ret; \
unsigned long flags; \
if (ANOMALY_05000473) \ if (ANOMALY_05000473) \
local_irq_disable(); \ local_irq_save(flags); \
__ret = bfin_read32((sport)->port.membase + OFFSET_RX); \ __ret = bfin_read32((sport)->port.membase + OFFSET_RX); \
if (ANOMALY_05000473) \ if (ANOMALY_05000473) \
local_irq_enable(); \ local_irq_restore(flags); \
__ret; \ __ret; \
}) })
#define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1))
......
...@@ -116,15 +116,22 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) ...@@ -116,15 +116,22 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id)
{ {
struct bfin_serial_port *uart = dev_id; struct bfin_serial_port *uart = dev_id;
unsigned int status; unsigned int status = bfin_serial_get_mctrl(&uart->port);
status = bfin_serial_get_mctrl(&uart->port);
uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
uart->scts = 1; struct tty_struct *tty = uart->port.state->port.tty;
UART_CLEAR_SCTS(uart); UART_CLEAR_SCTS(uart);
UART_CLEAR_IER(uart, EDSSI); if (tty->hw_stopped) {
if (status) {
tty->hw_stopped = 0;
uart_write_wakeup(&uart->port);
}
} else {
if (!status)
tty->hw_stopped = 1;
}
#endif #endif
uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -175,13 +182,6 @@ static void bfin_serial_start_tx(struct uart_port *port) ...@@ -175,13 +182,6 @@ static void bfin_serial_start_tx(struct uart_port *port)
struct bfin_serial_port *uart = (struct bfin_serial_port *)port; struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
struct tty_struct *tty = uart->port.state->port.tty; struct tty_struct *tty = uart->port.state->port.tty;
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) {
uart->scts = 0;
uart_handle_cts_change(&uart->port, uart->scts);
}
#endif
/* /*
* To avoid losting RX interrupt, we reset IR function * To avoid losting RX interrupt, we reset IR function
* before sending data. * before sending data.
...@@ -380,12 +380,6 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) ...@@ -380,12 +380,6 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
{ {
struct bfin_serial_port *uart = dev_id; struct bfin_serial_port *uart = dev_id;
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) {
uart->scts = 0;
uart_handle_cts_change(&uart->port, uart->scts);
}
#endif
spin_lock(&uart->port.lock); spin_lock(&uart->port.lock);
if (UART_GET_LSR(uart) & THRE) if (UART_GET_LSR(uart) & THRE)
bfin_serial_tx_chars(uart); bfin_serial_tx_chars(uart);
...@@ -531,13 +525,6 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) ...@@ -531,13 +525,6 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
struct bfin_serial_port *uart = dev_id; struct bfin_serial_port *uart = dev_id;
struct circ_buf *xmit = &uart->port.state->xmit; struct circ_buf *xmit = &uart->port.state->xmit;
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
uart->scts = 0;
uart_handle_cts_change(&uart->port, uart->scts);
}
#endif
spin_lock(&uart->port.lock); spin_lock(&uart->port.lock);
if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
disable_dma(uart->tx_dma_channel); disable_dma(uart->tx_dma_channel);
...@@ -739,20 +726,26 @@ static int bfin_serial_startup(struct uart_port *port) ...@@ -739,20 +726,26 @@ static int bfin_serial_startup(struct uart_port *port)
pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n");
} }
} }
if (uart->rts_pin >= 0) if (uart->rts_pin >= 0) {
if (gpio_request(uart->rts_pin, DRIVER_NAME)) {
pr_info("fail to request RTS PIN at GPIO_%d\n", uart->rts_pin);
uart->rts_pin = -1;
} else
gpio_direction_output(uart->rts_pin, 0); gpio_direction_output(uart->rts_pin, 0);
}
#endif #endif
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
if (uart->cts_pin >= 0 && request_irq(uart->status_irq, if (uart->cts_pin >= 0) {
bfin_serial_mctrl_cts_int, if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int,
0, "BFIN_UART_MODEM_STATUS", uart)) { IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
uart->cts_pin = -1; uart->cts_pin = -1;
pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); dev_info(port->dev, "Unable to attach BlackFin UART Modem Status interrupt.\n");
} }
/* CTS RTS PINs are negative assertive. */ /* CTS RTS PINs are negative assertive. */
UART_PUT_MCR(uart, ACTS); UART_PUT_MCR(uart, ACTS);
UART_SET_IER(uart, EDSSI); UART_SET_IER(uart, EDSSI);
}
#endif #endif
UART_SET_IER(uart, ERBFI); UART_SET_IER(uart, ERBFI);
...@@ -792,6 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port) ...@@ -792,6 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port)
#ifdef CONFIG_SERIAL_BFIN_CTSRTS #ifdef CONFIG_SERIAL_BFIN_CTSRTS
if (uart->cts_pin >= 0) if (uart->cts_pin >= 0)
free_irq(gpio_to_irq(uart->cts_pin), uart); free_irq(gpio_to_irq(uart->cts_pin), uart);
if (uart->rts_pin >= 0)
gpio_free(uart->rts_pin);
#endif #endif
#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
if (uart->cts_pin >= 0) if (uart->cts_pin >= 0)
...@@ -1370,18 +1365,18 @@ static int bfin_serial_probe(struct platform_device *pdev) ...@@ -1370,18 +1365,18 @@ static int bfin_serial_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IO, 0); res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (res == NULL) if (res == NULL)
uart->cts_pin = -1; uart->cts_pin = -1;
else else {
uart->cts_pin = res->start; uart->cts_pin = res->start;
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
uart->port.flags |= ASYNC_CTS_FLOW;
#endif
}
res = platform_get_resource(pdev, IORESOURCE_IO, 1); res = platform_get_resource(pdev, IORESOURCE_IO, 1);
if (res == NULL) if (res == NULL)
uart->rts_pin = -1; uart->rts_pin = -1;
else else
uart->rts_pin = res->start; uart->rts_pin = res->start;
# if defined(CONFIG_SERIAL_BFIN_CTSRTS)
if (uart->rts_pin >= 0)
gpio_request(uart->rts_pin, DRIVER_NAME);
# endif
#endif #endif
} }
...@@ -1421,10 +1416,6 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev) ...@@ -1421,10 +1416,6 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev)
if (uart) { if (uart) {
uart_remove_one_port(&bfin_serial_reg, &uart->port); uart_remove_one_port(&bfin_serial_reg, &uart->port);
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
if (uart->rts_pin >= 0)
gpio_free(uart->rts_pin);
#endif
iounmap(uart->port.membase); iounmap(uart->port.membase);
peripheral_free_list( peripheral_free_list(
(unsigned short *)pdev->dev.platform_data); (unsigned short *)pdev->dev.platform_data);
......
...@@ -1334,7 +1334,6 @@ MODULE_DEVICE_TABLE(spi, ifx_id_table); ...@@ -1334,7 +1334,6 @@ MODULE_DEVICE_TABLE(spi, ifx_id_table);
static const struct spi_driver ifx_spi_driver = { static const struct spi_driver ifx_spi_driver = {
.driver = { .driver = {
.name = DRVNAME, .name = DRVNAME,
.bus = &spi_bus_type,
.pm = &ifx_spi_pm, .pm = &ifx_spi_pm,
.owner = THIS_MODULE}, .owner = THIS_MODULE},
.probe = ifx_spi_spi_probe, .probe = ifx_spi_spi_probe,
......
...@@ -102,6 +102,7 @@ ...@@ -102,6 +102,7 @@
#define UCR2_STPB (1<<6) /* Stop */ #define UCR2_STPB (1<<6) /* Stop */
#define UCR2_WS (1<<5) /* Word size */ #define UCR2_WS (1<<5) /* Word size */
#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
#define UCR2_ATEN (1<<3) /* Aging Timer Enable */
#define UCR2_TXEN (1<<2) /* Transmitter enabled */ #define UCR2_TXEN (1<<2) /* Transmitter enabled */
#define UCR2_RXEN (1<<1) /* Receiver enabled */ #define UCR2_RXEN (1<<1) /* Receiver enabled */
#define UCR2_SRST (1<<0) /* SW reset */ #define UCR2_SRST (1<<0) /* SW reset */
...@@ -207,6 +208,12 @@ struct imx_port { ...@@ -207,6 +208,12 @@ struct imx_port {
struct imx_uart_data *devdata; struct imx_uart_data *devdata;
}; };
struct imx_port_ucrs {
unsigned int ucr1;
unsigned int ucr2;
unsigned int ucr3;
};
#ifdef CONFIG_IRDA #ifdef CONFIG_IRDA
#define USE_IRDA(sport) ((sport)->use_irda) #define USE_IRDA(sport) ((sport)->use_irda)
#else #else
...@@ -259,6 +266,27 @@ static inline int is_imx21_uart(struct imx_port *sport) ...@@ -259,6 +266,27 @@ static inline int is_imx21_uart(struct imx_port *sport)
return sport->devdata->devtype == IMX21_UART; return sport->devdata->devtype == IMX21_UART;
} }
/*
* Save and restore functions for UCR1, UCR2 and UCR3 registers
*/
static void imx_port_ucrs_save(struct uart_port *port,
struct imx_port_ucrs *ucr)
{
/* save control registers */
ucr->ucr1 = readl(port->membase + UCR1);
ucr->ucr2 = readl(port->membase + UCR2);
ucr->ucr3 = readl(port->membase + UCR3);
}
static void imx_port_ucrs_restore(struct uart_port *port,
struct imx_port_ucrs *ucr)
{
/* restore control registers */
writel(ucr->ucr1, port->membase + UCR1);
writel(ucr->ucr2, port->membase + UCR2);
writel(ucr->ucr3, port->membase + UCR3);
}
/* /*
* Handle any change of modem status signal since we were last called. * Handle any change of modem status signal since we were last called.
*/ */
...@@ -566,6 +594,9 @@ static irqreturn_t imx_int(int irq, void *dev_id) ...@@ -566,6 +594,9 @@ static irqreturn_t imx_int(int irq, void *dev_id)
if (sts & USR1_RTSD) if (sts & USR1_RTSD)
imx_rtsint(irq, dev_id); imx_rtsint(irq, dev_id);
if (sts & USR1_AWAKE)
writel(USR1_AWAKE, sport->port.membase + USR1);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -901,6 +932,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -901,6 +932,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
ucr2 |= UCR2_PROE; ucr2 |= UCR2_PROE;
} }
del_timer_sync(&sport->timer);
/* /*
* Ask the core to calculate the divisor for us. * Ask the core to calculate the divisor for us.
*/ */
...@@ -931,8 +964,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -931,8 +964,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
sport->port.ignore_status_mask |= URXD_OVRRUN; sport->port.ignore_status_mask |= URXD_OVRRUN;
} }
del_timer_sync(&sport->timer);
/* /*
* Update the per-port timeout. * Update the per-port timeout.
*/ */
...@@ -1079,6 +1110,70 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) ...@@ -1079,6 +1110,70 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
return ret; return ret;
} }
#if defined(CONFIG_CONSOLE_POLL)
static int imx_poll_get_char(struct uart_port *port)
{
struct imx_port_ucrs old_ucr;
unsigned int status;
unsigned char c;
/* save control registers */
imx_port_ucrs_save(port, &old_ucr);
/* disable interrupts */
writel(UCR1_UARTEN, port->membase + UCR1);
writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
port->membase + UCR2);
writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN),
port->membase + UCR3);
/* poll */
do {
status = readl(port->membase + USR2);
} while (~status & USR2_RDR);
/* read */
c = readl(port->membase + URXD0);
/* restore control registers */
imx_port_ucrs_restore(port, &old_ucr);
return c;
}
static void imx_poll_put_char(struct uart_port *port, unsigned char c)
{
struct imx_port_ucrs old_ucr;
unsigned int status;
/* save control registers */
imx_port_ucrs_save(port, &old_ucr);
/* disable interrupts */
writel(UCR1_UARTEN, port->membase + UCR1);
writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
port->membase + UCR2);
writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN),
port->membase + UCR3);
/* drain */
do {
status = readl(port->membase + USR1);
} while (~status & USR1_TRDY);
/* write */
writel(c, port->membase + URTX0);
/* flush */
do {
status = readl(port->membase + USR2);
} while (~status & USR2_TXDC);
/* restore control registers */
imx_port_ucrs_restore(port, &old_ucr);
}
#endif
static struct uart_ops imx_pops = { static struct uart_ops imx_pops = {
.tx_empty = imx_tx_empty, .tx_empty = imx_tx_empty,
.set_mctrl = imx_set_mctrl, .set_mctrl = imx_set_mctrl,
...@@ -1096,6 +1191,10 @@ static struct uart_ops imx_pops = { ...@@ -1096,6 +1191,10 @@ static struct uart_ops imx_pops = {
.request_port = imx_request_port, .request_port = imx_request_port,
.config_port = imx_config_port, .config_port = imx_config_port,
.verify_port = imx_verify_port, .verify_port = imx_verify_port,
#if defined(CONFIG_CONSOLE_POLL)
.poll_get_char = imx_poll_get_char,
.poll_put_char = imx_poll_put_char,
#endif
}; };
static struct imx_port *imx_ports[UART_NR]; static struct imx_port *imx_ports[UART_NR];
...@@ -1118,13 +1217,14 @@ static void ...@@ -1118,13 +1217,14 @@ static void
imx_console_write(struct console *co, const char *s, unsigned int count) imx_console_write(struct console *co, const char *s, unsigned int count)
{ {
struct imx_port *sport = imx_ports[co->index]; struct imx_port *sport = imx_ports[co->index];
unsigned int old_ucr1, old_ucr2, ucr1; struct imx_port_ucrs old_ucr;
unsigned int ucr1;
/* /*
* First, save UCR1/2 and then disable interrupts * First, save UCR1/2/3 and then disable interrupts
*/ */
ucr1 = old_ucr1 = readl(sport->port.membase + UCR1); imx_port_ucrs_save(&sport->port, &old_ucr);
old_ucr2 = readl(sport->port.membase + UCR2); ucr1 = old_ucr.ucr1;
if (is_imx1_uart(sport)) if (is_imx1_uart(sport))
ucr1 |= IMX1_UCR1_UARTCLKEN; ucr1 |= IMX1_UCR1_UARTCLKEN;
...@@ -1133,18 +1233,17 @@ imx_console_write(struct console *co, const char *s, unsigned int count) ...@@ -1133,18 +1233,17 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
writel(ucr1, sport->port.membase + UCR1); writel(ucr1, sport->port.membase + UCR1);
writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2); writel(old_ucr.ucr2 | UCR2_TXEN, sport->port.membase + UCR2);
uart_console_write(&sport->port, s, count, imx_console_putchar); uart_console_write(&sport->port, s, count, imx_console_putchar);
/* /*
* Finally, wait for transmitter to become empty * Finally, wait for transmitter to become empty
* and restore UCR1/2 * and restore UCR1/2/3
*/ */
while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); while (!(readl(sport->port.membase + USR2) & USR2_TXDC));
writel(old_ucr1, sport->port.membase + UCR1); imx_port_ucrs_restore(&sport->port, &old_ucr);
writel(old_ucr2, sport->port.membase + UCR2);
} }
/* /*
...@@ -1269,6 +1368,12 @@ static struct uart_driver imx_reg = { ...@@ -1269,6 +1368,12 @@ static struct uart_driver imx_reg = {
static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
{ {
struct imx_port *sport = platform_get_drvdata(dev); struct imx_port *sport = platform_get_drvdata(dev);
unsigned int val;
/* enable wakeup from i.MX UART */
val = readl(sport->port.membase + UCR3);
val |= UCR3_AWAKEN;
writel(val, sport->port.membase + UCR3);
if (sport) if (sport)
uart_suspend_port(&imx_reg, &sport->port); uart_suspend_port(&imx_reg, &sport->port);
...@@ -1279,6 +1384,12 @@ static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) ...@@ -1279,6 +1384,12 @@ static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
static int serial_imx_resume(struct platform_device *dev) static int serial_imx_resume(struct platform_device *dev)
{ {
struct imx_port *sport = platform_get_drvdata(dev); struct imx_port *sport = platform_get_drvdata(dev);
unsigned int val;
/* disable wakeup from i.MX UART */
val = readl(sport->port.membase + UCR3);
val &= ~UCR3_AWAKEN;
writel(val, sport->port.membase + UCR3);
if (sport) if (sport)
uart_resume_port(&imx_reg, &sport->port); uart_resume_port(&imx_reg, &sport->port);
...@@ -1287,6 +1398,10 @@ static int serial_imx_resume(struct platform_device *dev) ...@@ -1287,6 +1398,10 @@ static int serial_imx_resume(struct platform_device *dev)
} }
#ifdef CONFIG_OF #ifdef CONFIG_OF
/*
* This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it
* could successfully get all information from dt or a negative errno.
*/
static int serial_imx_probe_dt(struct imx_port *sport, static int serial_imx_probe_dt(struct imx_port *sport,
struct platform_device *pdev) struct platform_device *pdev)
{ {
...@@ -1296,12 +1411,13 @@ static int serial_imx_probe_dt(struct imx_port *sport, ...@@ -1296,12 +1411,13 @@ static int serial_imx_probe_dt(struct imx_port *sport,
int ret; int ret;
if (!np) if (!np)
return -ENODEV; /* no device tree device */
return 1;
ret = of_alias_get_id(np, "serial"); ret = of_alias_get_id(np, "serial");
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
return -ENODEV; return ret;
} }
sport->port.line = ret; sport->port.line = ret;
...@@ -1319,7 +1435,7 @@ static int serial_imx_probe_dt(struct imx_port *sport, ...@@ -1319,7 +1435,7 @@ static int serial_imx_probe_dt(struct imx_port *sport,
static inline int serial_imx_probe_dt(struct imx_port *sport, static inline int serial_imx_probe_dt(struct imx_port *sport,
struct platform_device *pdev) struct platform_device *pdev)
{ {
return -ENODEV; return 1;
} }
#endif #endif
...@@ -1354,8 +1470,10 @@ static int serial_imx_probe(struct platform_device *pdev) ...@@ -1354,8 +1470,10 @@ static int serial_imx_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
ret = serial_imx_probe_dt(sport, pdev); ret = serial_imx_probe_dt(sport, pdev);
if (ret == -ENODEV) if (ret > 0)
serial_imx_probe_pdata(sport, pdev); serial_imx_probe_pdata(sport, pdev);
else if (ret < 0)
goto free;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res) {
...@@ -1476,7 +1594,7 @@ static int __init imx_serial_init(void) ...@@ -1476,7 +1594,7 @@ static int __init imx_serial_init(void)
if (ret != 0) if (ret != 0)
uart_unregister_driver(&imx_reg); uart_unregister_driver(&imx_reg);
return 0; return ret;
} }
static void __exit imx_serial_exit(void) static void __exit imx_serial_exit(void)
......
...@@ -1000,11 +1000,8 @@ static void __init m32r_sio_register_ports(struct uart_driver *drv) ...@@ -1000,11 +1000,8 @@ static void __init m32r_sio_register_ports(struct uart_driver *drv)
init_timer(&up->timer); init_timer(&up->timer);
up->timer.function = m32r_sio_timeout; up->timer.function = m32r_sio_timeout;
/* up->mcr_mask = ~0;
* ALPHA_KLUDGE_MCR needs to be killed. up->mcr_force = 0;
*/
up->mcr_mask = ~ALPHA_KLUDGE_MCR;
up->mcr_force = ALPHA_KLUDGE_MCR;
uart_add_one_port(drv, &up->port); uart_add_one_port(drv, &up->port);
} }
......
...@@ -901,7 +901,6 @@ static int max3100_resume(struct spi_device *spi) ...@@ -901,7 +901,6 @@ static int max3100_resume(struct spi_device *spi)
static struct spi_driver max3100_driver = { static struct spi_driver max3100_driver = {
.driver = { .driver = {
.name = "max3100", .name = "max3100",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
......
...@@ -315,7 +315,6 @@ static int __devinit max3107_probe_aava(struct spi_device *spi) ...@@ -315,7 +315,6 @@ static int __devinit max3107_probe_aava(struct spi_device *spi)
static struct spi_driver max3107_driver = { static struct spi_driver max3107_driver = {
.driver = { .driver = {
.name = "aava-max3107", .name = "aava-max3107",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = max3107_probe_aava, .probe = max3107_probe_aava,
......
...@@ -1181,7 +1181,6 @@ static int max3107_probe_generic(struct spi_device *spi) ...@@ -1181,7 +1181,6 @@ static int max3107_probe_generic(struct spi_device *spi)
static struct spi_driver max3107_driver = { static struct spi_driver max3107_driver = {
.driver = { .driver = {
.name = "max3107", .name = "max3107",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = max3107_probe_generic, .probe = max3107_probe_generic,
......
...@@ -1154,7 +1154,6 @@ serial_hsu_console_setup(struct console *co, char *options) ...@@ -1154,7 +1154,6 @@ serial_hsu_console_setup(struct console *co, char *options)
int bits = 8; int bits = 8;
int parity = 'n'; int parity = 'n';
int flow = 'n'; int flow = 'n';
int ret;
if (co->index == -1 || co->index >= serial_hsu_reg.nr) if (co->index == -1 || co->index >= serial_hsu_reg.nr)
co->index = 0; co->index = 0;
...@@ -1165,9 +1164,7 @@ serial_hsu_console_setup(struct console *co, char *options) ...@@ -1165,9 +1164,7 @@ serial_hsu_console_setup(struct console *co, char *options)
if (options) if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow); uart_parse_options(options, &baud, &parity, &bits, &flow);
ret = uart_set_options(&up->port, co, baud, parity, bits, flow); return uart_set_options(&up->port, co, baud, parity, bits, flow);
return ret;
} }
static struct console serial_hsu_console = { static struct console serial_hsu_console = {
...@@ -1176,9 +1173,13 @@ static struct console serial_hsu_console = { ...@@ -1176,9 +1173,13 @@ static struct console serial_hsu_console = {
.device = uart_console_device, .device = uart_console_device,
.setup = serial_hsu_console_setup, .setup = serial_hsu_console_setup,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
.index = 2, .index = -1,
.data = &serial_hsu_reg, .data = &serial_hsu_reg,
}; };
#define SERIAL_HSU_CONSOLE (&serial_hsu_console)
#else
#define SERIAL_HSU_CONSOLE NULL
#endif #endif
struct uart_ops serial_hsu_pops = { struct uart_ops serial_hsu_pops = {
...@@ -1208,6 +1209,7 @@ static struct uart_driver serial_hsu_reg = { ...@@ -1208,6 +1209,7 @@ static struct uart_driver serial_hsu_reg = {
.major = TTY_MAJOR, .major = TTY_MAJOR,
.minor = 128, .minor = 128,
.nr = 3, .nr = 3,
.cons = SERIAL_HSU_CONSOLE,
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1342,12 +1344,6 @@ static int serial_hsu_probe(struct pci_dev *pdev, ...@@ -1342,12 +1344,6 @@ static int serial_hsu_probe(struct pci_dev *pdev,
} }
uart_add_one_port(&serial_hsu_reg, &uport->port); uart_add_one_port(&serial_hsu_reg, &uport->port);
#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE
if (index == 2) {
register_console(&serial_hsu_console);
uport->port.cons = &serial_hsu_console;
}
#endif
pci_set_drvdata(pdev, uport); pci_set_drvdata(pdev, uport);
} }
......
...@@ -876,7 +876,6 @@ static int __devexit serial_m3110_remove(struct spi_device *dev) ...@@ -876,7 +876,6 @@ static int __devexit serial_m3110_remove(struct spi_device *dev)
static struct spi_driver uart_max3110_driver = { static struct spi_driver uart_max3110_driver = {
.driver = { .driver = {
.name = "spi_max3111", .name = "spi_max3111",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = serial_m3110_probe, .probe = serial_m3110_probe,
......
...@@ -422,9 +422,9 @@ static int __devexit msm_hs_remove(struct platform_device *pdev) ...@@ -422,9 +422,9 @@ static int __devexit msm_hs_remove(struct platform_device *pdev)
msm_uport->rx.rbuffer); msm_uport->rx.rbuffer);
dma_pool_destroy(msm_uport->rx.pool); dma_pool_destroy(msm_uport->rx.pool);
dma_unmap_single(dev, msm_uport->rx.cmdptr_dmaaddr, sizeof(u32 *), dma_unmap_single(dev, msm_uport->rx.cmdptr_dmaaddr, sizeof(u32),
DMA_TO_DEVICE); DMA_TO_DEVICE);
dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr_ptr, sizeof(u32 *), dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr_ptr, sizeof(u32),
DMA_TO_DEVICE); DMA_TO_DEVICE);
dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr, sizeof(dmov_box), dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr, sizeof(dmov_box),
DMA_TO_DEVICE); DMA_TO_DEVICE);
...@@ -812,7 +812,7 @@ static void msm_hs_submit_tx_locked(struct uart_port *uport) ...@@ -812,7 +812,7 @@ static void msm_hs_submit_tx_locked(struct uart_port *uport)
*tx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(tx->mapped_cmd_ptr); *tx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(tx->mapped_cmd_ptr);
dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr, dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr,
sizeof(u32 *), DMA_TO_DEVICE); sizeof(u32), DMA_TO_DEVICE);
/* Save tx_count to use in Callback */ /* Save tx_count to use in Callback */
tx->tx_count = tx_count; tx->tx_count = tx_count;
...@@ -1087,12 +1087,10 @@ static void msm_hs_config_port(struct uart_port *uport, int cfg_flags) ...@@ -1087,12 +1087,10 @@ static void msm_hs_config_port(struct uart_port *uport, int cfg_flags)
} }
/* Handle CTS changes (Called from interrupt handler) */ /* Handle CTS changes (Called from interrupt handler) */
static void msm_hs_handle_delta_cts(struct uart_port *uport) static void msm_hs_handle_delta_cts_locked(struct uart_port *uport)
{ {
unsigned long flags;
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
spin_lock_irqsave(&uport->lock, flags);
clk_enable(msm_uport->clk); clk_enable(msm_uport->clk);
/* clear interrupt */ /* clear interrupt */
...@@ -1100,7 +1098,6 @@ static void msm_hs_handle_delta_cts(struct uart_port *uport) ...@@ -1100,7 +1098,6 @@ static void msm_hs_handle_delta_cts(struct uart_port *uport)
uport->icount.cts++; uport->icount.cts++;
clk_disable(msm_uport->clk); clk_disable(msm_uport->clk);
spin_unlock_irqrestore(&uport->lock, flags);
/* clear the IOCTL TIOCMIWAIT if called */ /* clear the IOCTL TIOCMIWAIT if called */
wake_up_interruptible(&uport->state->port.delta_msr_wait); wake_up_interruptible(&uport->state->port.delta_msr_wait);
...@@ -1248,7 +1245,7 @@ static irqreturn_t msm_hs_isr(int irq, void *dev) ...@@ -1248,7 +1245,7 @@ static irqreturn_t msm_hs_isr(int irq, void *dev)
/* Change in CTS interrupt */ /* Change in CTS interrupt */
if (isr_status & UARTDM_ISR_DELTA_CTS_BMSK) if (isr_status & UARTDM_ISR_DELTA_CTS_BMSK)
msm_hs_handle_delta_cts(uport); msm_hs_handle_delta_cts_locked(uport);
spin_unlock_irqrestore(&uport->lock, flags); spin_unlock_irqrestore(&uport->lock, flags);
...@@ -1537,7 +1534,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) ...@@ -1537,7 +1534,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport)
if (!tx->command_ptr) if (!tx->command_ptr)
return -ENOMEM; return -ENOMEM;
tx->command_ptr_ptr = kmalloc(sizeof(u32 *), GFP_KERNEL | __GFP_DMA); tx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
if (!tx->command_ptr_ptr) { if (!tx->command_ptr_ptr) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_tx_command_ptr_ptr; goto err_tx_command_ptr_ptr;
...@@ -1547,7 +1544,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) ...@@ -1547,7 +1544,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport)
sizeof(dmov_box), DMA_TO_DEVICE); sizeof(dmov_box), DMA_TO_DEVICE);
tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev, tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev,
tx->command_ptr_ptr, tx->command_ptr_ptr,
sizeof(u32 *), DMA_TO_DEVICE); sizeof(u32), DMA_TO_DEVICE);
tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr); tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr);
init_waitqueue_head(&rx->wait); init_waitqueue_head(&rx->wait);
...@@ -1575,7 +1572,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) ...@@ -1575,7 +1572,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport)
goto err_rx_command_ptr; goto err_rx_command_ptr;
} }
rx->command_ptr_ptr = kmalloc(sizeof(u32 *), GFP_KERNEL | __GFP_DMA); rx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
if (!rx->command_ptr_ptr) { if (!rx->command_ptr_ptr) {
pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__); pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__);
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1593,7 +1590,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) ...@@ -1593,7 +1590,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport)
*rx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(rx->mapped_cmd_ptr); *rx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(rx->mapped_cmd_ptr);
rx->cmdptr_dmaaddr = dma_map_single(uport->dev, rx->command_ptr_ptr, rx->cmdptr_dmaaddr = dma_map_single(uport->dev, rx->command_ptr_ptr,
sizeof(u32 *), DMA_TO_DEVICE); sizeof(u32), DMA_TO_DEVICE);
rx->xfer.cmdptr = DMOV_CMD_ADDR(rx->cmdptr_dmaaddr); rx->xfer.cmdptr = DMOV_CMD_ADDR(rx->cmdptr_dmaaddr);
INIT_WORK(&rx->tty_work, msm_hs_tty_flip_buffer_work); INIT_WORK(&rx->tty_work, msm_hs_tty_flip_buffer_work);
...@@ -1609,7 +1606,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) ...@@ -1609,7 +1606,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport)
dma_pool_destroy(msm_uport->rx.pool); dma_pool_destroy(msm_uport->rx.pool);
err_dma_pool_create: err_dma_pool_create:
dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr, dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr,
sizeof(u32 *), DMA_TO_DEVICE); sizeof(u32), DMA_TO_DEVICE);
dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr, dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr,
sizeof(dmov_box), DMA_TO_DEVICE); sizeof(dmov_box), DMA_TO_DEVICE);
kfree(msm_uport->tx.command_ptr_ptr); kfree(msm_uport->tx.command_ptr_ptr);
......
...@@ -145,11 +145,12 @@ static inline void mxs_auart_tx_chars(struct mxs_auart_port *s) ...@@ -145,11 +145,12 @@ static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
writel(xmit->buf[xmit->tail], writel(xmit->buf[xmit->tail],
s->port.membase + AUART_DATA); s->port.membase + AUART_DATA);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&s->port);
} else } else
break; break;
} }
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&s->port);
if (uart_circ_empty(&(s->port.state->xmit))) if (uart_circ_empty(&(s->port.state->xmit)))
writel(AUART_INTR_TXIEN, writel(AUART_INTR_TXIEN,
s->port.membase + AUART_INTR_CLR); s->port.membase + AUART_INTR_CLR);
......
...@@ -399,7 +399,7 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port) ...@@ -399,7 +399,7 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)
static unsigned int serial_omap_get_mctrl(struct uart_port *port) static unsigned int serial_omap_get_mctrl(struct uart_port *port)
{ {
struct uart_omap_port *up = (struct uart_omap_port *)port; struct uart_omap_port *up = (struct uart_omap_port *)port;
unsigned char status; unsigned int status;
unsigned int ret = 0; unsigned int ret = 0;
status = check_modem_status(up); status = check_modem_status(up);
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/console.h>
#include <linux/nmi.h>
#include <linux/delay.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/pch_dma.h> #include <linux/pch_dma.h>
...@@ -198,6 +201,10 @@ enum { ...@@ -198,6 +201,10 @@ enum {
#define PCI_VENDOR_ID_ROHM 0x10DB #define PCI_VENDOR_ID_ROHM 0x10DB
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
#define DEFAULT_BAUD_RATE 1843200 /* 1.8432MHz */
struct pch_uart_buffer { struct pch_uart_buffer {
unsigned char *buf; unsigned char *buf;
int size; int size;
...@@ -276,6 +283,9 @@ static struct pch_uart_driver_data drv_dat[] = { ...@@ -276,6 +283,9 @@ static struct pch_uart_driver_data drv_dat[] = {
[pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, [pch_ml7831_uart1] = {PCH_UART_2LINE, 1},
}; };
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
static struct eg20t_port *pch_uart_ports[PCH_UART_NR];
#endif
static unsigned int default_baud = 9600; static unsigned int default_baud = 9600;
static const int trigger_level_256[4] = { 1, 64, 128, 224 }; static const int trigger_level_256[4] = { 1, 64, 128, 224 };
static const int trigger_level_64[4] = { 1, 16, 32, 56 }; static const int trigger_level_64[4] = { 1, 16, 32, 56 };
...@@ -1385,6 +1395,143 @@ static struct uart_ops pch_uart_ops = { ...@@ -1385,6 +1395,143 @@ static struct uart_ops pch_uart_ops = {
.verify_port = pch_uart_verify_port .verify_port = pch_uart_verify_port
}; };
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
/*
* Wait for transmitter & holding register to empty
*/
static void wait_for_xmitr(struct eg20t_port *up, int bits)
{
unsigned int status, tmout = 10000;
/* Wait up to 10ms for the character(s) to be sent. */
for (;;) {
status = ioread8(up->membase + UART_LSR);
if ((status & bits) == bits)
break;
if (--tmout == 0)
break;
udelay(1);
}
/* Wait up to 1s for flow control if necessary */
if (up->port.flags & UPF_CONS_FLOW) {
unsigned int tmout;
for (tmout = 1000000; tmout; tmout--) {
unsigned int msr = ioread8(up->membase + UART_MSR);
if (msr & UART_MSR_CTS)
break;
udelay(1);
touch_nmi_watchdog();
}
}
}
static void pch_console_putchar(struct uart_port *port, int ch)
{
struct eg20t_port *priv =
container_of(port, struct eg20t_port, port);
wait_for_xmitr(priv, UART_LSR_THRE);
iowrite8(ch, priv->membase + PCH_UART_THR);
}
/*
* 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
pch_console_write(struct console *co, const char *s, unsigned int count)
{
struct eg20t_port *priv;
unsigned long flags;
u8 ier;
int locked = 1;
priv = pch_uart_ports[co->index];
touch_nmi_watchdog();
local_irq_save(flags);
if (priv->port.sysrq) {
/* serial8250_handle_port() already took the lock */
locked = 0;
} else if (oops_in_progress) {
locked = spin_trylock(&priv->port.lock);
} else
spin_lock(&priv->port.lock);
/*
* First save the IER then disable the interrupts
*/
ier = ioread8(priv->membase + UART_IER);
pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
uart_console_write(&priv->port, s, count, pch_console_putchar);
/*
* Finally, wait for transmitter to become empty
* and restore the IER
*/
wait_for_xmitr(priv, BOTH_EMPTY);
iowrite8(ier, priv->membase + UART_IER);
if (locked)
spin_unlock(&priv->port.lock);
local_irq_restore(flags);
}
static int __init pch_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int baud = 9600;
int bits = 8;
int parity = 'n';
int flow = 'n';
/*
* Check whether an invalid uart number has been specified, and
* if so, search for the first available port that does have
* console support.
*/
if (co->index >= PCH_UART_NR)
co->index = 0;
port = &pch_uart_ports[co->index]->port;
if (!port || (!port->iobase && !port->membase))
return -ENODEV;
/* setup uartclock */
port->uartclk = DEFAULT_BAUD_RATE;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
return uart_set_options(port, co, baud, parity, bits, flow);
}
static struct uart_driver pch_uart_driver;
static struct console pch_console = {
.name = PCH_UART_DRIVER_DEVICE,
.write = pch_console_write,
.device = uart_console_device,
.setup = pch_console_setup,
.flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1,
.data = &pch_uart_driver,
};
#define PCH_CONSOLE (&pch_console)
#else
#define PCH_CONSOLE NULL
#endif
static struct uart_driver pch_uart_driver = { static struct uart_driver pch_uart_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.driver_name = KBUILD_MODNAME, .driver_name = KBUILD_MODNAME,
...@@ -1392,6 +1539,7 @@ static struct uart_driver pch_uart_driver = { ...@@ -1392,6 +1539,7 @@ static struct uart_driver pch_uart_driver = {
.major = 0, .major = 0,
.minor = 0, .minor = 0,
.nr = PCH_UART_NR, .nr = PCH_UART_NR,
.cons = PCH_CONSOLE,
}; };
static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
...@@ -1418,7 +1566,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, ...@@ -1418,7 +1566,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
if (!rxbuf) if (!rxbuf)
goto init_port_free_txbuf; goto init_port_free_txbuf;
base_baud = 1843200; /* 1.8432MHz */ base_baud = DEFAULT_BAUD_RATE;
/* quirk for CM-iTC board */ /* quirk for CM-iTC board */
board_name = dmi_get_system_info(DMI_BOARD_NAME); board_name = dmi_get_system_info(DMI_BOARD_NAME);
...@@ -1468,6 +1616,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, ...@@ -1468,6 +1616,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
pci_set_drvdata(pdev, priv); pci_set_drvdata(pdev, priv);
pch_uart_hal_request(pdev, fifosize, base_baud); pch_uart_hal_request(pdev, fifosize, base_baud);
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
pch_uart_ports[board->line_no] = priv;
#endif
ret = uart_add_one_port(&pch_uart_driver, &priv->port); ret = uart_add_one_port(&pch_uart_driver, &priv->port);
if (ret < 0) if (ret < 0)
goto init_port_hal_free; goto init_port_hal_free;
...@@ -1475,6 +1626,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, ...@@ -1475,6 +1626,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
return priv; return priv;
init_port_hal_free: init_port_hal_free:
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
pch_uart_ports[board->line_no] = NULL;
#endif
free_page((unsigned long)rxbuf); free_page((unsigned long)rxbuf);
init_port_free_txbuf: init_port_free_txbuf:
kfree(priv); kfree(priv);
...@@ -1497,6 +1651,10 @@ static void pch_uart_pci_remove(struct pci_dev *pdev) ...@@ -1497,6 +1651,10 @@ static void pch_uart_pci_remove(struct pci_dev *pdev)
priv = (struct eg20t_port *)pci_get_drvdata(pdev); priv = (struct eg20t_port *)pci_get_drvdata(pdev);
pci_disable_msi(pdev); pci_disable_msi(pdev);
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
pch_uart_ports[priv->port.line] = NULL;
#endif
pch_uart_exit_port(priv); pch_uart_exit_port(priv);
pci_disable_device(pdev); pci_disable_device(pdev);
kfree(priv); kfree(priv);
......
...@@ -736,19 +736,7 @@ static struct platform_driver sc26xx_driver = { ...@@ -736,19 +736,7 @@ static struct platform_driver sc26xx_driver = {
}, },
}; };
static int __init sc26xx_init(void) module_platform_driver(sc26xx_driver);
{
return platform_driver_register(&sc26xx_driver);
}
static void __exit sc26xx_exit(void)
{
platform_driver_unregister(&sc26xx_driver);
}
module_init(sc26xx_init);
module_exit(sc26xx_exit);
MODULE_AUTHOR("Thomas Bogendörfer"); MODULE_AUTHOR("Thomas Bogendörfer");
MODULE_DESCRIPTION("SC681/SC2692 serial driver"); MODULE_DESCRIPTION("SC681/SC2692 serial driver");
......
This diff is collapsed.
...@@ -317,7 +317,7 @@ static int serial_probe(struct pcmcia_device *link) ...@@ -317,7 +317,7 @@ static int serial_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->config_flags |= CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
if (do_sound) if (do_sound)
link->config_flags |= CONF_ENABLE_SPKR; link->config_flags |= CONF_ENABLE_SPKR;
...@@ -445,7 +445,7 @@ static int simple_config(struct pcmcia_device *link) ...@@ -445,7 +445,7 @@ static int simple_config(struct pcmcia_device *link)
/* First pass: look for a config entry that looks normal. /* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */ * Two tries: without IO aliases, then with aliases */
link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO; link->config_flags |= CONF_AUTO_SET_VPP;
for (try = 0; try < 4; try++) for (try = 0; try < 4; try++)
if (!pcmcia_loop_config(link, simple_config_check, &try)) if (!pcmcia_loop_config(link, simple_config_check, &try))
goto found_port; goto found_port;
...@@ -501,7 +501,8 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev, ...@@ -501,7 +501,8 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
{ {
int *base2 = priv_data; int *base2 = priv_data;
if (!p_dev->resource[0]->end || !p_dev->resource[1]->end) if (!p_dev->resource[0]->end || !p_dev->resource[1]->end ||
p_dev->resource[0]->start + 8 != p_dev->resource[1]->start)
return -ENODEV; return -ENODEV;
p_dev->resource[0]->end = p_dev->resource[1]->end = 8; p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
...@@ -520,7 +521,6 @@ static int multi_config(struct pcmcia_device *link) ...@@ -520,7 +521,6 @@ static int multi_config(struct pcmcia_device *link)
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
int i, base2 = 0; int i, base2 = 0;
link->config_flags |= CONF_AUTO_SET_IO;
/* First, look for a generic full-sized window */ /* First, look for a generic full-sized window */
if (!pcmcia_loop_config(link, multi_config_check, &info->multi)) if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
base2 = link->resource[0]->start + 8; base2 = link->resource[0]->start + 8;
......
This diff is collapsed.
/*
* Drivers for CSR SiRFprimaII onboard UARTs.
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
* Licensed under GPLv2 or later.
*/
#include <linux/bitops.h>
/* UART Register Offset Define */
#define SIRFUART_LINE_CTRL 0x0040
#define SIRFUART_TX_RX_EN 0x004c
#define SIRFUART_DIVISOR 0x0050
#define SIRFUART_INT_EN 0x0054
#define SIRFUART_INT_STATUS 0x0058
#define SIRFUART_TX_DMA_IO_CTRL 0x0100
#define SIRFUART_TX_DMA_IO_LEN 0x0104
#define SIRFUART_TX_FIFO_CTRL 0x0108
#define SIRFUART_TX_FIFO_LEVEL_CHK 0x010C
#define SIRFUART_TX_FIFO_OP 0x0110
#define SIRFUART_TX_FIFO_STATUS 0x0114
#define SIRFUART_TX_FIFO_DATA 0x0118
#define SIRFUART_RX_DMA_IO_CTRL 0x0120
#define SIRFUART_RX_DMA_IO_LEN 0x0124
#define SIRFUART_RX_FIFO_CTRL 0x0128
#define SIRFUART_RX_FIFO_LEVEL_CHK 0x012C
#define SIRFUART_RX_FIFO_OP 0x0130
#define SIRFUART_RX_FIFO_STATUS 0x0134
#define SIRFUART_RX_FIFO_DATA 0x0138
#define SIRFUART_AFC_CTRL 0x0140
#define SIRFUART_SWH_DMA_IO 0x0148
/* UART Line Control Register */
#define SIRFUART_DATA_BIT_LEN_MASK 0x3
#define SIRFUART_DATA_BIT_LEN_5 BIT(0)
#define SIRFUART_DATA_BIT_LEN_6 1
#define SIRFUART_DATA_BIT_LEN_7 2
#define SIRFUART_DATA_BIT_LEN_8 3
#define SIRFUART_STOP_BIT_LEN_1 0
#define SIRFUART_STOP_BIT_LEN_2 BIT(2)
#define SIRFUART_PARITY_EN BIT(3)
#define SIRFUART_EVEN_BIT BIT(4)
#define SIRFUART_STICK_BIT_MASK (7 << 3)
#define SIRFUART_STICK_BIT_NONE (0 << 3)
#define SIRFUART_STICK_BIT_EVEN BIT(3)
#define SIRFUART_STICK_BIT_ODD (3 << 3)
#define SIRFUART_STICK_BIT_MARK (5 << 3)
#define SIRFUART_STICK_BIT_SPACE (7 << 3)
#define SIRFUART_SET_BREAK BIT(6)
#define SIRFUART_LOOP_BACK BIT(7)
#define SIRFUART_PARITY_MASK (7 << 3)
#define SIRFUART_DUMMY_READ BIT(16)
#define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000)
#define SIRFUART_RECV_TIMEOUT_MASK (0xFFFF << 16)
#define SIRFUART_RECV_TIMEOUT(x) (((x) & 0xFFFF) << 16)
/* UART Auto Flow Control */
#define SIRFUART_AFC_RX_THD_MASK 0x000000FF
#define SIRFUART_AFC_RX_EN BIT(8)
#define SIRFUART_AFC_TX_EN BIT(9)
#define SIRFUART_CTS_CTRL BIT(10)
#define SIRFUART_RTS_CTRL BIT(11)
#define SIRFUART_CTS_IN_STATUS BIT(12)
#define SIRFUART_RTS_OUT_STATUS BIT(13)
/* UART Interrupt Enable Register */
#define SIRFUART_RX_DONE_INT BIT(0)
#define SIRFUART_TX_DONE_INT BIT(1)
#define SIRFUART_RX_OFLOW_INT BIT(2)
#define SIRFUART_TX_ALLOUT_INT BIT(3)
#define SIRFUART_RX_IO_DMA_INT BIT(4)
#define SIRFUART_TX_IO_DMA_INT BIT(5)
#define SIRFUART_RXFIFO_FULL_INT BIT(6)
#define SIRFUART_TXFIFO_EMPTY_INT BIT(7)
#define SIRFUART_RXFIFO_THD_INT BIT(8)
#define SIRFUART_TXFIFO_THD_INT BIT(9)
#define SIRFUART_FRM_ERR_INT BIT(10)
#define SIRFUART_RXD_BREAK_INT BIT(11)
#define SIRFUART_RX_TIMEOUT_INT BIT(12)
#define SIRFUART_PARITY_ERR_INT BIT(13)
#define SIRFUART_CTS_INT_EN BIT(14)
#define SIRFUART_RTS_INT_EN BIT(15)
/* UART Interrupt Status Register */
#define SIRFUART_RX_DONE BIT(0)
#define SIRFUART_TX_DONE BIT(1)
#define SIRFUART_RX_OFLOW BIT(2)
#define SIRFUART_TX_ALL_EMPTY BIT(3)
#define SIRFUART_DMA_IO_RX_DONE BIT(4)
#define SIRFUART_DMA_IO_TX_DONE BIT(5)
#define SIRFUART_RXFIFO_FULL BIT(6)
#define SIRFUART_TXFIFO_EMPTY BIT(7)
#define SIRFUART_RXFIFO_THD_REACH BIT(8)
#define SIRFUART_TXFIFO_THD_REACH BIT(9)
#define SIRFUART_FRM_ERR BIT(10)
#define SIRFUART_RXD_BREAK BIT(11)
#define SIRFUART_RX_TIMEOUT BIT(12)
#define SIRFUART_PARITY_ERR BIT(13)
#define SIRFUART_CTS_CHANGE BIT(14)
#define SIRFUART_RTS_CHANGE BIT(15)
#define SIRFUART_PLUG_IN BIT(16)
#define SIRFUART_ERR_INT_STAT \
(SIRFUART_RX_OFLOW | \
SIRFUART_FRM_ERR | \
SIRFUART_RXD_BREAK | \
SIRFUART_PARITY_ERR)
#define SIRFUART_ERR_INT_EN \
(SIRFUART_RX_OFLOW_INT | \
SIRFUART_FRM_ERR_INT | \
SIRFUART_RXD_BREAK_INT | \
SIRFUART_PARITY_ERR_INT)
#define SIRFUART_TX_INT_EN SIRFUART_TXFIFO_EMPTY_INT
#define SIRFUART_RX_IO_INT_EN \
(SIRFUART_RX_TIMEOUT_INT | \
SIRFUART_RXFIFO_THD_INT | \
SIRFUART_RXFIFO_FULL_INT | \
SIRFUART_ERR_INT_EN)
/* UART FIFO Register */
#define SIRFUART_TX_FIFO_STOP 0x0
#define SIRFUART_TX_FIFO_RESET 0x1
#define SIRFUART_TX_FIFO_START 0x2
#define SIRFUART_RX_FIFO_STOP 0x0
#define SIRFUART_RX_FIFO_RESET 0x1
#define SIRFUART_RX_FIFO_START 0x2
#define SIRFUART_TX_MODE_DMA 0
#define SIRFUART_TX_MODE_IO 1
#define SIRFUART_RX_MODE_DMA 0
#define SIRFUART_RX_MODE_IO 1
#define SIRFUART_RX_EN 0x1
#define SIRFUART_TX_EN 0x2
/* Generic Definitions */
#define SIRFSOC_UART_NAME "ttySiRF"
#define SIRFSOC_UART_MAJOR 0
#define SIRFSOC_UART_MINOR 0
#define SIRFUART_PORT_NAME "sirfsoc-uart"
#define SIRFUART_MAP_SIZE 0x200
#define SIRFSOC_UART_NR 3
#define SIRFSOC_PORT_TYPE 0xa5
/* Baud Rate Calculation */
#define SIRF_MIN_SAMPLE_DIV 0xf
#define SIRF_MAX_SAMPLE_DIV 0x3f
#define SIRF_IOCLK_DIV_MAX 0xffff
#define SIRF_SAMPLE_DIV_SHIFT 16
#define SIRF_IOCLK_DIV_MASK 0xffff
#define SIRF_SAMPLE_DIV_MASK 0x3f0000
#define SIRF_BAUD_RATE_SUPPORT_NR 18
/* For Fast Baud Rate Calculation */
struct sirfsoc_baudrate_to_regv {
unsigned int baud_rate;
unsigned int reg_val;
};
struct sirfsoc_uart_port {
unsigned char hw_flow_ctrl;
unsigned char ms_enabled;
struct uart_port port;
struct pinmux *pmx;
};
/* Hardware Flow Control */
#define SIRFUART_AFC_CTRL_RX_THD 0x70
/* Register Access Control */
#define portaddr(port, reg) ((port)->membase + (reg))
#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
/* UART Port Mask */
#define SIRFUART_FIFOLEVEL_MASK(port) ((port->line == 1) ? (0x1f) : (0x7f))
#define SIRFUART_FIFOFULL_MASK(port) ((port->line == 1) ? (0x20) : (0x80))
#define SIRFUART_FIFOEMPTY_MASK(port) ((port->line == 1) ? (0x40) : (0x100))
/* I/O Mode */
#define SIRFSOC_UART_IO_RX_MAX_CNT 256
#define SIRFSOC_UART_IO_TX_REASONABLE_CNT 6
...@@ -513,20 +513,7 @@ static struct platform_driver timbuart_platform_driver = { ...@@ -513,20 +513,7 @@ static struct platform_driver timbuart_platform_driver = {
.remove = __devexit_p(timbuart_remove), .remove = __devexit_p(timbuart_remove),
}; };
/*--------------------------------------------------------------------------*/ module_platform_driver(timbuart_platform_driver);
static int __init timbuart_init(void)
{
return platform_driver_register(&timbuart_platform_driver);
}
static void __exit timbuart_exit(void)
{
platform_driver_unregister(&timbuart_platform_driver);
}
module_init(timbuart_init);
module_exit(timbuart_exit);
MODULE_DESCRIPTION("Timberdale UART driver"); MODULE_DESCRIPTION("Timberdale UART driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
......
...@@ -961,18 +961,7 @@ static struct platform_driver siu_device_driver = { ...@@ -961,18 +961,7 @@ static struct platform_driver siu_device_driver = {
}, },
}; };
static int __init vr41xx_siu_init(void) module_platform_driver(siu_device_driver);
{
return platform_driver_register(&siu_device_driver);
}
static void __exit vr41xx_siu_exit(void)
{
platform_driver_unregister(&siu_device_driver);
}
module_init(vr41xx_siu_init);
module_exit(vr41xx_siu_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:SIU"); MODULE_ALIAS("platform:SIU");
This diff is collapsed.
#include <linux/types.h> #include <linux/types.h>
#include <linux/major.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/signal.h> #include <linux/kmod.h>
#include <linux/fcntl.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/tty_driver.h> #include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/devpts_fs.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/console.h>
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/kd.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -24,18 +16,8 @@ ...@@ -24,18 +16,8 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/system.h>
#include <linux/kbd_kern.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/kmod.h>
#include <linux/nsproxy.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
/* /*
...@@ -558,8 +540,6 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) ...@@ -558,8 +540,6 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
long ret; long ret;
ret = wait_event_timeout(tty_ldisc_idle, ret = wait_event_timeout(tty_ldisc_idle,
atomic_read(&tty->ldisc->users) == 1, timeout); atomic_read(&tty->ldisc->users) == 1, timeout);
if (ret < 0)
return ret;
return ret > 0 ? 0 : -EBUSY; return ret > 0 ? 0 : -EBUSY;
} }
......
...@@ -584,7 +584,7 @@ int con_set_default_unimap(struct vc_data *vc) ...@@ -584,7 +584,7 @@ int con_set_default_unimap(struct vc_data *vc)
return 0; return 0;
dflt->refcount++; dflt->refcount++;
*vc->vc_uni_pagedir_loc = (unsigned long)dflt; *vc->vc_uni_pagedir_loc = (unsigned long)dflt;
if (p && --p->refcount) { if (p && !--p->refcount) {
con_release_unimap(p); con_release_unimap(p);
kfree(p); kfree(p);
} }
......
...@@ -66,6 +66,7 @@ enum { ...@@ -66,6 +66,7 @@ enum {
* dependent on the 8250 driver. * dependent on the 8250 driver.
*/ */
struct uart_port; struct uart_port;
struct uart_8250_port;
int serial8250_register_port(struct uart_port *); int serial8250_register_port(struct uart_port *);
void serial8250_unregister_port(int line); void serial8250_unregister_port(int line);
...@@ -81,7 +82,11 @@ extern void serial8250_do_set_termios(struct uart_port *port, ...@@ -81,7 +82,11 @@ extern void serial8250_do_set_termios(struct uart_port *port,
struct ktermios *termios, struct ktermios *old); struct ktermios *termios, struct ktermios *old);
extern void serial8250_do_pm(struct uart_port *port, unsigned int state, extern void serial8250_do_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate); unsigned int oldstate);
extern int fsl8250_handle_irq(struct uart_port *port);
int serial8250_handle_irq(struct uart_port *port, unsigned int iir); int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr);
void serial8250_tx_chars(struct uart_8250_port *up);
unsigned int serial8250_modem_status(struct uart_8250_port *up);
extern void serial8250_set_isa_configurator(void (*v) extern void serial8250_set_isa_configurator(void (*v)
(int port, struct uart_port *up, (int port, struct uart_port *up,
......
...@@ -351,6 +351,7 @@ struct uart_port { ...@@ -351,6 +351,7 @@ struct uart_port {
#define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
#define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) #define UPF_EXAR_EFR ((__force upf_t) (1 << 25))
#define UPF_IIR_ONCE ((__force upf_t) (1 << 26))
/* The exact UART type is known and should not be probed. */ /* The exact UART type is known and should not be probed. */
#define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27))
#define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28))
...@@ -483,10 +484,19 @@ static inline int uart_tx_stopped(struct uart_port *port) ...@@ -483,10 +484,19 @@ static inline int uart_tx_stopped(struct uart_port *port)
/* /*
* The following are helper functions for the low level drivers. * The following are helper functions for the low level drivers.
*/ */
extern void uart_handle_dcd_change(struct uart_port *uport,
unsigned int status);
extern void uart_handle_cts_change(struct uart_port *uport,
unsigned int status);
extern void uart_insert_char(struct uart_port *port, unsigned int status,
unsigned int overrun, unsigned int ch, unsigned int flag);
#ifdef SUPPORT_SYSRQ
static inline int static inline int
uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
{ {
#ifdef SUPPORT_SYSRQ
if (port->sysrq) { if (port->sysrq) {
if (ch && time_before(jiffies, port->sysrq)) { if (ch && time_before(jiffies, port->sysrq)) {
handle_sysrq(ch); handle_sysrq(ch);
...@@ -495,11 +505,10 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) ...@@ -495,11 +505,10 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
} }
port->sysrq = 0; port->sysrq = 0;
} }
#endif
return 0; return 0;
} }
#ifndef SUPPORT_SYSRQ #else
#define uart_handle_sysrq_char(port,ch) uart_handle_sysrq_char(port, 0) #define uart_handle_sysrq_char(port,ch) ({ (void)port; 0; })
#endif #endif
/* /*
...@@ -522,89 +531,6 @@ static inline int uart_handle_break(struct uart_port *port) ...@@ -522,89 +531,6 @@ static inline int uart_handle_break(struct uart_port *port)
return 0; return 0;
} }
/**
* uart_handle_dcd_change - handle a change of carrier detect state
* @uport: uart_port structure for the open port
* @status: new carrier detect status, nonzero if active
*/
static inline void
uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
{
struct uart_state *state = uport->state;
struct tty_port *port = &state->port;
struct tty_ldisc *ld = tty_ldisc_ref(port->tty);
struct pps_event_time ts;
if (ld && ld->ops->dcd_change)
pps_get_ts(&ts);
uport->icount.dcd++;
#ifdef CONFIG_HARD_PPS
if ((uport->flags & UPF_HARDPPS_CD) && status)
hardpps();
#endif
if (port->flags & ASYNC_CHECK_CD) {
if (status)
wake_up_interruptible(&port->open_wait);
else if (port->tty)
tty_hangup(port->tty);
}
if (ld && ld->ops->dcd_change)
ld->ops->dcd_change(port->tty, status, &ts);
if (ld)
tty_ldisc_deref(ld);
}
/**
* uart_handle_cts_change - handle a change of clear-to-send state
* @uport: uart_port structure for the open port
* @status: new clear to send status, nonzero if active
*/
static inline void
uart_handle_cts_change(struct uart_port *uport, unsigned int status)
{
struct tty_port *port = &uport->state->port;
struct tty_struct *tty = port->tty;
uport->icount.cts++;
if (port->flags & ASYNC_CTS_FLOW) {
if (tty->hw_stopped) {
if (status) {
tty->hw_stopped = 0;
uport->ops->start_tx(uport);
uart_write_wakeup(uport);
}
} else {
if (!status) {
tty->hw_stopped = 1;
uport->ops->stop_tx(uport);
}
}
}
}
#include <linux/tty_flip.h>
static inline void
uart_insert_char(struct uart_port *port, unsigned int status,
unsigned int overrun, unsigned int ch, unsigned int flag)
{
struct tty_struct *tty = port->state->port.tty;
if ((status & port->ignore_status_mask & ~overrun) == 0)
tty_insert_flip_char(tty, ch, flag);
/*
* Overrun is special. Since it's reported immediately,
* it doesn't affect the current character.
*/
if (status & ~port->ignore_status_mask & overrun)
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
/* /*
* UART_ENABLE_MS - determine if port should enable modem status irqs * UART_ENABLE_MS - determine if port should enable modem status irqs
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment