1
0
Fork 0

TTY/Serial patches for 5.9-rc1

Here is the large set of TTY and Serial driver patches for 5.9-rc1.
 
 Lots of bugfixes in here, thanks to syzbot fuzzing for serial and vt and
 console code.
 
 Other highlights include:
 	- much needed vt/vc code cleanup from Jiri Slaby
 	- 8250 driver fixes and additions
 	- various serial driver updates and feature enhancements
 	- locking cleanup for serial/console initializations
 	- other minor cleanups
 
 All of these have been in linux-next with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXyv30A8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ynW+gCgv+OqxT0jeNRAMSQcpMvP3wTBMKIAn1StfjJ4
 y8uwZuQQimD49uj8XtDq
 =bKSv
 -----END PGP SIGNATURE-----

Merge tag 'tty-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial updates from Greg KH:
 "Here is the large set of TTY and Serial driver patches for 5.9-rc1.

  Lots of bugfixes in here, thanks to syzbot fuzzing for serial and vt
  and console code.

  Other highlights include:

   - much needed vt/vc code cleanup from Jiri Slaby

   - 8250 driver fixes and additions

   - various serial driver updates and feature enhancements

   - locking cleanup for serial/console initializations

   - other minor cleanups

  All of these have been in linux-next with no reported issues"

* tag 'tty-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (90 commits)
  MAINTAINERS: enlist Greg formally for console stuff
  vgacon: Fix for missing check in scrollback handling
  Revert "serial: 8250: Let serial core initialise spin lock"
  serial: 8250: Let serial core initialise spin lock
  tty: keyboard, do not speculate on func_table index
  serial: stm32: Add RS485 RTS GPIO control
  serial: 8250_dw: Fix common clocks usage race condition
  serial: 8250_dw: Pass the same rate to the clk round and set rate methods
  serial: 8250_dw: Simplify the ref clock rate setting procedure
  serial: 8250: Add 8250 port clock update method
  tty: serial: imx: add imx earlycon driver
  tty: serial: imx: enable imx serial console port as module
  tty/synclink: remove leftover bits of non-PCI card support
  tty: Use the preferred form for passing the size of a structure type
  tty: Fix identation issues in struct serial_struct32
  tty: Avoid the use of one-element arrays
  serial: msm_serial: add sparse context annotation
  serial: pmac_zilog: add sparse context annotation
  newport_con: vc_color is now in state
  serial: imx: use hrtimers for rs485 delays
  ...
zero-sugar-mainline-defconfig
Linus Torvalds 2020-08-06 14:56:11 -07:00
commit d6efb3ac3e
63 changed files with 1846 additions and 1612 deletions

View File

@ -35,9 +35,11 @@ properties:
description: label associated with this uart
st,hw-flow-ctrl:
description: enable hardware flow control
description: enable hardware flow control (deprecated)
$ref: /schemas/types.yaml#/definitions/flag
uart-has-rtscts: true
dmas:
minItems: 1
maxItems: 2

View File

@ -5,7 +5,7 @@ GSM 0710 tty multiplexor HOWTO
This line discipline implements the GSM 07.10 multiplexing protocol
detailed in the following 3GPP document:
http://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
https://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
This document give some hints on how to use this driver with GPRS and 3G
modems connected to a physical serial port.

View File

@ -4386,6 +4386,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/connector/
CONSOLE SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
S: Supported
F: drivers/video/console/
F: include/linux/console*
CONTROL GROUP (CGROUP)
M: Tejun Heo <tj@kernel.org>
M: Li Zefan <lizefan@huawei.com>

View File

@ -184,11 +184,6 @@ void line_flush_chars(struct tty_struct *tty)
line_flush_buffer(tty);
}
int line_put_char(struct tty_struct *tty, unsigned char ch)
{
return line_write(tty, &ch, sizeof(ch));
}
int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
struct line *line = tty->driver_data;

View File

@ -66,7 +66,6 @@ extern int line_setup(char **conf, unsigned nlines, char **def,
char *init, char *name);
extern int line_write(struct tty_struct *tty, const unsigned char *buf,
int len);
extern int line_put_char(struct tty_struct *tty, unsigned char ch);
extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
extern int line_chars_in_buffer(struct tty_struct *tty);
extern void line_flush_buffer(struct tty_struct *tty);

View File

@ -95,7 +95,6 @@ static const struct tty_operations ssl_ops = {
.open = line_open,
.close = line_close,
.write = line_write,
.put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
.flush_buffer = line_flush_buffer,

View File

@ -102,7 +102,6 @@ static const struct tty_operations console_ops = {
.install = con_install,
.close = line_close,
.write = line_write,
.put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
.flush_buffer = line_flush_buffer,

View File

@ -109,16 +109,16 @@ static void braille_write(u16 *buf)
/* Follow the VC cursor*/
static void vc_follow_cursor(struct vc_data *vc)
{
vc_x = vc->vc_x - (vc->vc_x % WIDTH);
vc_y = vc->vc_y;
lastvc_x = vc->vc_x;
lastvc_y = vc->vc_y;
vc_x = vc->state.x - (vc->state.x % WIDTH);
vc_y = vc->state.y;
lastvc_x = vc->state.x;
lastvc_y = vc->state.y;
}
/* Maybe the VC cursor moved, if so follow it */
static void vc_maybe_cursor_moved(struct vc_data *vc)
{
if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y)
if (vc->state.x != lastvc_x || vc->state.y != lastvc_y)
vc_follow_cursor(vc);
}

View File

@ -263,8 +263,8 @@ static unsigned char get_attributes(struct vc_data *vc, u16 *pos)
static void speakup_date(struct vc_data *vc)
{
spk_x = spk_cx = vc->vc_x;
spk_y = spk_cy = vc->vc_y;
spk_x = spk_cx = vc->state.x;
spk_y = spk_cy = vc->state.y;
spk_pos = spk_cp = vc->vc_pos;
spk_old_attr = spk_attr;
spk_attr = get_attributes(vc, (u_short *)spk_pos);
@ -1551,9 +1551,9 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag)
*/
is_cursor = value + 1;
old_cursor_pos = vc->vc_pos;
old_cursor_x = vc->vc_x;
old_cursor_y = vc->vc_y;
speakup_console[vc->vc_num]->ht.cy = vc->vc_y;
old_cursor_x = vc->state.x;
old_cursor_y = vc->state.y;
speakup_console[vc->vc_num]->ht.cy = vc->state.y;
cursor_con = vc->vc_num;
if (cursor_track == CT_Highlight)
reset_highlight_buffers(vc);
@ -1574,8 +1574,8 @@ static void update_color_buffer(struct vc_data *vc, const u16 *ic, int len)
i = 0;
if (speakup_console[vc_num]->ht.highsize[bi] == 0) {
speakup_console[vc_num]->ht.rpos[bi] = vc->vc_pos;
speakup_console[vc_num]->ht.rx[bi] = vc->vc_x;
speakup_console[vc_num]->ht.ry[bi] = vc->vc_y;
speakup_console[vc_num]->ht.rx[bi] = vc->state.x;
speakup_console[vc_num]->ht.ry[bi] = vc->state.y;
}
while ((hi < COLOR_BUFFER_SIZE) && (i < len)) {
if (ic[i] > 32) {
@ -1664,9 +1664,9 @@ static int speak_highlight(struct vc_data *vc)
return 0;
hc = get_highlight_color(vc);
if (hc != -1) {
d = vc->vc_y - speakup_console[vc_num]->ht.cy;
d = vc->state.y - speakup_console[vc_num]->ht.cy;
if ((d == 1) || (d == -1))
if (speakup_console[vc_num]->ht.ry[hc] != vc->vc_y)
if (speakup_console[vc_num]->ht.ry[hc] != vc->state.y)
return 0;
spk_parked |= 0x01;
spk_do_flush();
@ -1693,8 +1693,8 @@ static void cursor_done(struct timer_list *unused)
}
speakup_date(vc);
if (win_enabled) {
if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
if (vc->state.x >= win_left && vc->state.x <= win_right &&
vc->state.y >= win_top && vc->state.y <= win_bottom) {
spk_keydown = 0;
is_cursor = 0;
goto out;
@ -1757,7 +1757,7 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len)
if (!spin_trylock_irqsave(&speakup_info.spinlock, flags))
/* Speakup output, discard */
return;
if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1))
if (spk_bell_pos && spk_keydown && (vc->state.x == spk_bell_pos - 1))
bleep(3);
if ((is_cursor) || (cursor_track == read_all_mode)) {
if (cursor_track == CT_Highlight)
@ -1766,8 +1766,8 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len)
return;
}
if (win_enabled) {
if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
if (vc->state.x >= win_left && vc->state.x <= win_right &&
vc->state.y >= win_top && vc->state.y <= win_bottom) {
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
return;
}

View File

@ -138,7 +138,7 @@
#define IntrQuit 0x40 /* received QUIT code */
#define IntrEOF 0x80 /* received EOF code */
#define IntrRxTrigger 0x100 /* rx data count reach tigger value */
#define IntrRxTrigger 0x100 /* rx data count reach trigger value */
#define IntrTxTrigger 0x200 /* tx data count below trigger value */
#define Magic_no (Config_base + 0)

View File

@ -19,6 +19,8 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/clk.h>
@ -43,6 +45,8 @@ struct dw8250_data {
int msr_mask_off;
struct clk *clk;
struct clk *pclk;
struct notifier_block clk_notifier;
struct work_struct clk_work;
struct reset_control *rst;
unsigned int skip_autocfg:1;
@ -54,6 +58,16 @@ static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
return container_of(data, struct dw8250_data, data);
}
static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb)
{
return container_of(nb, struct dw8250_data, clk_notifier);
}
static inline struct dw8250_data *work_to_dw8250_data(struct work_struct *work)
{
return container_of(work, struct dw8250_data, clk_work);
}
static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = to_dw8250_data(p->private_data);
@ -260,6 +274,46 @@ static int dw8250_handle_irq(struct uart_port *p)
return 0;
}
static void dw8250_clk_work_cb(struct work_struct *work)
{
struct dw8250_data *d = work_to_dw8250_data(work);
struct uart_8250_port *up;
unsigned long rate;
rate = clk_get_rate(d->clk);
if (rate <= 0)
return;
up = serial8250_get_port(d->data.line);
serial8250_update_uartclk(&up->port, rate);
}
static int dw8250_clk_notifier_cb(struct notifier_block *nb,
unsigned long event, void *data)
{
struct dw8250_data *d = clk_to_dw8250_data(nb);
/*
* We have no choice but to defer the uartclk update due to two
* deadlocks. First one is caused by a recursive mutex lock which
* happens when clk_set_rate() is called from dw8250_set_termios().
* Second deadlock is more tricky and is caused by an inverted order of
* the clk and tty-port mutexes lock. It happens if clock rate change
* is requested asynchronously while set_termios() is executed between
* tty-port mutex lock and clk_set_rate() function invocation and
* vise-versa. Anyway if we didn't have the reference clock alteration
* in the dw8250_set_termios() method we wouldn't have needed this
* deferred event handling complication.
*/
if (event == POST_RATE_CHANGE) {
queue_work(system_unbound_wq, &d->clk_work);
return NOTIFY_OK;
}
return NOTIFY_DONE;
}
static void
dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
{
@ -275,27 +329,27 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
struct ktermios *old)
{
unsigned int baud = tty_termios_baud_rate(termios);
unsigned long newrate = tty_termios_baud_rate(termios) * 16;
struct dw8250_data *d = to_dw8250_data(p->private_data);
long rate;
int ret;
clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16);
if (rate < 0)
ret = rate;
else if (rate == 0)
ret = -ENOENT;
else
ret = clk_set_rate(d->clk, rate);
rate = clk_round_rate(d->clk, newrate);
if (rate > 0) {
/*
* Premilinary set the uartclk to the new clock rate so the
* clock update event handler caused by the clk_set_rate()
* calling wouldn't actually update the UART divisor since
* we about to do this anyway.
*/
swap(p->uartclk, rate);
ret = clk_set_rate(d->clk, newrate);
if (ret)
swap(p->uartclk, rate);
}
clk_prepare_enable(d->clk);
if (ret)
goto out;
p->uartclk = rate;
out:
p->status &= ~UPSTAT_AUTOCTS;
if (termios->c_cflag & CRTSCTS)
p->status |= UPSTAT_AUTOCTS;
@ -319,6 +373,39 @@ static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios)
serial8250_do_set_ldisc(p, termios);
}
static int dw8250_startup(struct uart_port *p)
{
struct dw8250_data *d = to_dw8250_data(p->private_data);
int ret;
/*
* Some platforms may provide a reference clock shared between several
* devices. In this case before using the serial port first we have to
* make sure that any clock state change is known to the UART port at
* least post factum.
*/
if (d->clk) {
ret = clk_notifier_register(d->clk, &d->clk_notifier);
if (ret)
dev_warn(p->dev, "Failed to set the clock notifier\n");
}
return serial8250_do_startup(p);
}
static void dw8250_shutdown(struct uart_port *p)
{
struct dw8250_data *d = to_dw8250_data(p->private_data);
serial8250_do_shutdown(p);
if (d->clk) {
clk_notifier_unregister(d->clk, &d->clk_notifier);
flush_work(&d->clk_work);
}
}
/*
* dw8250_fallback_dma_filter will prevent the UART from getting just any free
* channel on platforms that have DMA engines, but don't have any channels
@ -414,6 +501,8 @@ static int dw8250_probe(struct platform_device *pdev)
p->serial_out = dw8250_serial_out;
p->set_ldisc = dw8250_set_ldisc;
p->set_termios = dw8250_set_termios;
p->startup = dw8250_startup;
p->shutdown = dw8250_shutdown;
p->membase = devm_ioremap(dev, regs->start, resource_size(regs));
if (!p->membase)
@ -475,6 +564,9 @@ static int dw8250_probe(struct platform_device *pdev)
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
INIT_WORK(&data->clk_work, dw8250_clk_work_cb);
data->clk_notifier.notifier_call = dw8250_clk_notifier_cb;
err = clk_prepare_enable(data->clk);
if (err)
dev_warn(dev, "could not enable optional baudclk: %d\n", err);

View File

@ -78,14 +78,18 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
static int serial8250_em_probe(struct platform_device *pdev)
{
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct serial8250_em_priv *priv;
struct uart_8250_port up;
int ret;
struct resource *regs;
int irq, ret;
if (!regs || !irq) {
dev_err(&pdev->dev, "missing registers or irq\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "missing registers\n");
return -EINVAL;
}
@ -101,7 +105,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
memset(&up, 0, sizeof(up));
up.port.mapbase = regs->start;
up.port.irq = irq->start;
up.port.irq = irq;
up.port.type = PORT_UNKNOWN;
up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
up.port.dev = &pdev->dev;

View File

@ -207,12 +207,11 @@ static unsigned int ingenic_uart_serial_in(struct uart_port *p, int offset)
static int ingenic_uart_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {};
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct ingenic_uart_data *data;
const struct ingenic_uart_config *cdata;
const struct of_device_id *match;
int err, line;
struct resource *regs;
int irq, err, line;
match = of_match_device(of_match, &pdev->dev);
if (!match) {
@ -221,8 +220,13 @@ static int ingenic_uart_probe(struct platform_device *pdev)
}
cdata = match->data;
if (!regs || !irq) {
dev_err(&pdev->dev, "no registers/irq defined\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "no registers defined\n");
return -EINVAL;
}
@ -238,7 +242,7 @@ static int ingenic_uart_probe(struct platform_device *pdev)
uart.port.regshift = 2;
uart.port.serial_out = ingenic_uart_serial_out;
uart.port.serial_in = ingenic_uart_serial_in;
uart.port.irq = irq->start;
uart.port.irq = irq;
uart.port.dev = &pdev->dev;
uart.port.fifosize = cdata->fifosize;
uart.tx_loadsz = cdata->tx_loadsz;

View File

@ -51,7 +51,7 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev)
return clkval;
}
static unsigned int get_num_ports(struct mcb_device *mdev,
static int get_num_ports(struct mcb_device *mdev,
void __iomem *membase)
{
switch (mdev->id) {
@ -140,7 +140,7 @@ static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
return;
num_ports = get_num_ports(mdev, data[0].uart.port.membase);
if (num_ports < 0 || num_ports > 4) {
if (num_ports <= 0 || num_ports > 4) {
dev_err(&mdev->dev, "error retrieving number of ports!\n");
return;
}

View File

@ -512,13 +512,17 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p,
static int mtk8250_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {};
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct mtk8250_data *data;
int err;
struct resource *regs;
int irq, err;
if (!regs || !irq) {
dev_err(&pdev->dev, "no registers/irq defined\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "no registers defined\n");
return -EINVAL;
}
@ -542,7 +546,7 @@ static int mtk8250_probe(struct platform_device *pdev)
spin_lock_init(&uart.port.lock);
uart.port.mapbase = regs->start;
uart.port.irq = irq->start;
uart.port.irq = irq;
uart.port.pm = mtk8250_do_pm;
uart.port.type = PORT_16550;
uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;

View File

@ -1209,17 +1209,21 @@ MODULE_DEVICE_TABLE(of, omap8250_dt_ids);
static int omap8250_probe(struct platform_device *pdev)
{
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct device_node *np = pdev->dev.of_node;
struct omap8250_priv *priv;
const struct omap8250_platdata *pdata;
struct uart_8250_port up;
int ret;
struct resource *regs;
void __iomem *membase;
int irq, ret;
if (!regs || !irq) {
dev_err(&pdev->dev, "missing registers or irq\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "missing registers\n");
return -EINVAL;
}
@ -1236,7 +1240,7 @@ static int omap8250_probe(struct platform_device *pdev)
up.port.dev = &pdev->dev;
up.port.mapbase = regs->start;
up.port.membase = membase;
up.port.irq = irq->start;
up.port.irq = irq;
/*
* It claims to be 16C750 compatible however it is a little different.
* It has EFR and has no FCR7_64byte bit. The AFE (which it claims to

View File

@ -16,6 +16,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/gpio/consumer.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
@ -2631,6 +2632,46 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
(port->uartclk + tolerance) / 16);
}
/*
* Note in order to avoid the tty port mutex deadlock don't use the next method
* within the uart port callbacks. Primarily it's supposed to be utilized to
* handle a sudden reference clock rate change.
*/
void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int baud, quot, frac = 0;
struct ktermios *termios;
unsigned long flags;
mutex_lock(&port->state->port.mutex);
if (port->uartclk == uartclk)
goto out_lock;
port->uartclk = uartclk;
termios = &port->state->port.tty->termios;
baud = serial8250_get_baud_rate(port, termios, NULL);
quot = serial8250_get_divisor(port, baud, &frac);
serial8250_rpm_get(up);
spin_lock_irqsave(&port->lock, flags);
uart_update_timeout(port, termios->c_cflag, baud);
serial8250_set_divisor(port, baud, quot, frac);
serial_port_out(port, UART_LCR, up->lcr);
serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
spin_unlock_irqrestore(&port->lock, flags);
serial8250_rpm_put(up);
out_lock:
mutex_unlock(&port->state->port.mutex);
}
EXPORT_SYMBOL_GPL(serial8250_update_uartclk);
void
serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)

View File

@ -18,7 +18,6 @@
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@ -93,12 +92,15 @@ static int serial_pxa_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {};
struct pxa8250_data *data;
struct resource *mmres, *irqres;
int ret;
struct resource *mmres;
int irq, ret;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!mmres || !irqres)
if (!mmres)
return -ENODEV;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
@ -121,7 +123,7 @@ static int serial_pxa_probe(struct platform_device *pdev)
uart.port.iotype = UPIO_MEM32;
uart.port.mapbase = mmres->start;
uart.port.regshift = 2;
uart.port.irq = irqres->start;
uart.port.irq = irq;
uart.port.fifosize = 64;
uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE;
uart.port.dev = &pdev->dev;

View File

@ -222,7 +222,7 @@ config SERIAL_8250_MANY_PORTS
Say Y here if you have dumb serial boards other than the four
standard COM 1/2/3/4 ports. This may happen if you have an AST
FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
from <http://www.tldp.org/docs.html#howto>), or other custom
from <https://www.tldp.org/docs.html#howto>), or other custom
serial port hardware which acts similar to standard serial port
hardware. If you only use the standard COM 1/2/3/4 ports, you can
say N here to save some memory. You can also say Y if you have an
@ -266,7 +266,7 @@ config SERIAL_8250_BOCA
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
Say Y here if you have a Boca serial board. Please read the Boca
mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
mini-HOWTO, available from <https://www.tldp.org/docs.html#howto>
To compile this driver as a module, choose M here: the module
will be called 8250_boca.

View File

@ -502,20 +502,27 @@ config SERIAL_IMX
can enable its onboard serial port by enabling this option.
config SERIAL_IMX_CONSOLE
bool "Console on IMX serial port"
depends on SERIAL_IMX=y
tristate "Console on IMX serial port"
depends on SERIAL_IMX
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON if OF
help
If you have enabled the serial port on the Freescale IMX
CPU you can make it the console by answering Y to this option.
CPU you can make it the console by answering Y/M to this option.
Even if you say Y here, the currently visible virtual console
Even if you say Y/M 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=ttymxc0". (Try "man bootparam" or see the documentation of
your bootloader about how to pass options to the kernel at boot time.)
config SERIAL_IMX_EARLYCON
bool "Earlycon on IMX serial port"
depends on OF
select SERIAL_EARLYCON
help
If you have enabled the earlycon on the Freescale IMX
CPU you can make it the earlycon by answering Y to this option.
config SERIAL_UARTLITE
tristate "Xilinx uartlite serial port support"
depends on HAS_IOMEM

View File

@ -27,7 +27,7 @@
/*
* Altera JTAG UART register definitions according to the Altera JTAG UART
* datasheet: http://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf
* datasheet: https://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf
*/
#define ALTERA_JTAGUART_SIZE 8

View File

@ -2607,7 +2607,6 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,
uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL011_CONSOLE);
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = index;
spin_lock_init(&uap->port.lock);
amba_ports[index] = uap;

View File

@ -1925,6 +1925,9 @@ static void __lpuart32_serial_setbrg(struct uart_port *port,
tmp_sbr++;
}
if (tmp_sbr > UARTBAUD_SBR_MASK)
continue;
if (tmp_diff <= baud_diff) {
baud_diff = tmp_diff;
osr = tmp_osr;

View File

@ -20,6 +20,7 @@
#include <linux/serial.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/ktime.h>
#include <linux/pinctrl/consumer.h>
#include <linux/rational.h>
#include <linux/slab.h>
@ -188,6 +189,13 @@ struct imx_uart_data {
enum imx_uart_type devtype;
};
enum imx_tx_state {
OFF,
WAIT_AFTER_RTS,
SEND,
WAIT_AFTER_SEND,
};
struct imx_port {
struct uart_port port;
struct timer_list timer;
@ -224,6 +232,10 @@ struct imx_port {
unsigned int dma_tx_nents;
unsigned int saved_reg[10];
bool context_saved;
enum imx_tx_state tx_state;
struct hrtimer trigger_start_tx;
struct hrtimer trigger_stop_tx;
};
struct imx_port_ucrs {
@ -361,7 +373,7 @@ static inline int imx_uart_is_imx6q(struct imx_port *sport)
/*
* Save and restore functions for UCR1, UCR2 and UCR3 registers
*/
#if defined(CONFIG_SERIAL_IMX_CONSOLE)
#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE)
static void imx_uart_ucrs_save(struct imx_port *sport,
struct imx_port_ucrs *ucr)
{
@ -400,6 +412,15 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
mctrl_gpio_set(sport->gpios, sport->port.mctrl);
}
static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
{
long sec = msec / MSEC_PER_SEC;
long nsec = (msec % MSEC_PER_SEC) * 1000000;
ktime_t t = ktime_set(sec, nsec);
hrtimer_start(hrt, t, HRTIMER_MODE_REL);
}
/* called with port.lock taken and irqs off */
static void imx_uart_start_rx(struct uart_port *port)
{
@ -427,7 +448,10 @@ static void imx_uart_start_rx(struct uart_port *port)
static void imx_uart_stop_tx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
u32 ucr1;
u32 ucr1, ucr4, usr2;
if (sport->tx_state == OFF)
return;
/*
* We are maybe in the SMP context, so if the DMA TX thread is running
@ -439,21 +463,44 @@ static void imx_uart_stop_tx(struct uart_port *port)
ucr1 = imx_uart_readl(sport, UCR1);
imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1);
/* in rs485 mode disable transmitter if shifter is empty */
if (port->rs485.flags & SER_RS485_ENABLED &&
imx_uart_readl(sport, USR2) & USR2_TXDC) {
u32 ucr2 = imx_uart_readl(sport, UCR2), ucr4;
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
imx_uart_rts_active(sport, &ucr2);
else
imx_uart_rts_inactive(sport, &ucr2);
imx_uart_writel(sport, ucr2, UCR2);
usr2 = imx_uart_readl(sport, USR2);
if (!(usr2 & USR2_TXDC)) {
/* The shifter is still busy, so retry once TC triggers */
return;
}
imx_uart_start_rx(port);
ucr4 = imx_uart_readl(sport, UCR4);
ucr4 &= ~UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4);
ucr4 = imx_uart_readl(sport, UCR4);
ucr4 &= ~UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4);
/* in rs485 mode disable transmitter */
if (port->rs485.flags & SER_RS485_ENABLED) {
if (sport->tx_state == SEND) {
sport->tx_state = WAIT_AFTER_SEND;
start_hrtimer_ms(&sport->trigger_stop_tx,
port->rs485.delay_rts_after_send);
return;
}
if (sport->tx_state == WAIT_AFTER_RTS ||
sport->tx_state == WAIT_AFTER_SEND) {
u32 ucr2;
hrtimer_try_to_cancel(&sport->trigger_start_tx);
ucr2 = imx_uart_readl(sport, UCR2);
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
imx_uart_rts_active(sport, &ucr2);
else
imx_uart_rts_inactive(sport, &ucr2);
imx_uart_writel(sport, ucr2, UCR2);
imx_uart_start_rx(port);
sport->tx_state = OFF;
}
} else {
sport->tx_state = OFF;
}
}
@ -651,28 +698,50 @@ static void imx_uart_start_tx(struct uart_port *port)
if (!sport->port.x_char && uart_circ_empty(&port->state->xmit))
return;
/*
* We cannot simply do nothing here if sport->tx_state == SEND already
* because UCR1_TXMPTYEN might already have been cleared in
* imx_uart_stop_tx(), but tx_state is still SEND.
*/
if (port->rs485.flags & SER_RS485_ENABLED) {
u32 ucr2;
if (sport->tx_state == OFF) {
u32 ucr2 = imx_uart_readl(sport, UCR2);
if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
imx_uart_rts_active(sport, &ucr2);
else
imx_uart_rts_inactive(sport, &ucr2);
imx_uart_writel(sport, ucr2, UCR2);
ucr2 = imx_uart_readl(sport, UCR2);
if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
imx_uart_rts_active(sport, &ucr2);
else
imx_uart_rts_inactive(sport, &ucr2);
imx_uart_writel(sport, ucr2, UCR2);
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
imx_uart_stop_rx(port);
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
imx_uart_stop_rx(port);
/*
* Enable transmitter and shifter empty irq only if DMA is off.
* In the DMA case this is done in the tx-callback.
*/
if (!sport->dma_is_enabled) {
u32 ucr4 = imx_uart_readl(sport, UCR4);
ucr4 |= UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4);
sport->tx_state = WAIT_AFTER_RTS;
start_hrtimer_ms(&sport->trigger_start_tx,
port->rs485.delay_rts_before_send);
return;
}
if (sport->tx_state == WAIT_AFTER_SEND
|| sport->tx_state == WAIT_AFTER_RTS) {
hrtimer_try_to_cancel(&sport->trigger_stop_tx);
/*
* Enable transmitter and shifter empty irq only if DMA
* is off. In the DMA case this is done in the
* tx-callback.
*/
if (!sport->dma_is_enabled) {
u32 ucr4 = imx_uart_readl(sport, UCR4);
ucr4 |= UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4);
}
sport->tx_state = SEND;
}
} else {
sport->tx_state = SEND;
}
if (!sport->dma_is_enabled) {
@ -1630,7 +1699,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_cflag & CRTSCTS)
ucr2 &= ~UCR2_IRTS;
if (termios->c_cflag & CSTOPB)
ucr2 |= UCR2_STPB;
if (termios->c_cflag & PARENB) {
@ -1857,10 +1925,6 @@ static int imx_uart_rs485_config(struct uart_port *port,
struct imx_port *sport = (struct imx_port *)port;
u32 ucr2;
/* unimplemented */
rs485conf->delay_rts_before_send = 0;
rs485conf->delay_rts_after_send = 0;
/* RTS is required to control the transmitter */
if (!sport->have_rtscts && !sport->have_rtsgpio)
rs485conf->flags &= ~SER_RS485_ENABLED;
@ -1915,7 +1979,7 @@ static const struct uart_ops imx_uart_pops = {
static struct imx_port *imx_uart_ports[UART_NR];
#ifdef CONFIG_SERIAL_IMX_CONSOLE
#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE)
static void imx_uart_console_putchar(struct uart_port *port, int ch)
{
struct imx_port *sport = (struct imx_port *)port;
@ -2112,39 +2176,6 @@ static struct console imx_uart_console = {
#define IMX_CONSOLE &imx_uart_console
#ifdef CONFIG_OF
static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
{
struct imx_port *sport = (struct imx_port *)port;
while (imx_uart_readl(sport, IMX21_UTS) & UTS_TXFULL)
cpu_relax();
imx_uart_writel(sport, ch, URTX0);
}
static void imx_uart_console_early_write(struct console *con, const char *s,
unsigned count)
{
struct earlycon_device *dev = con->data;
uart_console_write(&dev->port, s, count, imx_uart_console_early_putchar);
}
static int __init
imx_console_early_setup(struct earlycon_device *dev, const char *opt)
{
if (!dev->port.membase)
return -ENODEV;
dev->con->write = imx_uart_console_early_write;
return 0;
}
OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup);
OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup);
#endif
#else
#define IMX_CONSOLE NULL
#endif
@ -2223,6 +2254,32 @@ static void imx_uart_probe_pdata(struct imx_port *sport,
sport->have_rtscts = 1;
}
static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t)
{
struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx);
unsigned long flags;
spin_lock_irqsave(&sport->port.lock, flags);
if (sport->tx_state == WAIT_AFTER_RTS)
imx_uart_start_tx(&sport->port);
spin_unlock_irqrestore(&sport->port.lock, flags);
return HRTIMER_NORESTART;
}
static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t)
{
struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx);
unsigned long flags;
spin_lock_irqsave(&sport->port.lock, flags);
if (sport->tx_state == WAIT_AFTER_SEND)
imx_uart_stop_tx(&sport->port);
spin_unlock_irqrestore(&sport->port.lock, flags);
return HRTIMER_NORESTART;
}
static int imx_uart_probe(struct platform_device *pdev)
{
struct imx_port *sport;
@ -2369,6 +2426,11 @@ static int imx_uart_probe(struct platform_device *pdev)
clk_disable_unprepare(sport->clk_ipg);
hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
sport->trigger_start_tx.function = imx_trigger_start_tx;
sport->trigger_stop_tx.function = imx_trigger_stop_tx;
/*
* Allocate the IRQ(s) i.MX1 has three interrupts whereas later
* chips only have one interrupt.
@ -2406,9 +2468,6 @@ static int imx_uart_probe(struct platform_device *pdev)
}
}
/* We need to initialize lock even for non-registered console */
spin_lock_init(&sport->port.lock);
imx_uart_ports[sport->port.line] = sport;
platform_set_drvdata(pdev, sport);

View File

@ -0,0 +1,50 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2020 NXP
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/io.h>
#define URTX0 0x40 /* Transmitter Register */
#define UTS_TXFULL (1<<4) /* TxFIFO full */
#define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/
static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
{
while (readl_relaxed(port->membase + IMX21_UTS) & UTS_TXFULL)
cpu_relax();
writel_relaxed(ch, port->membase + URTX0);
}
static void imx_uart_console_early_write(struct console *con, const char *s,
unsigned count)
{
struct earlycon_device *dev = con->data;
uart_console_write(&dev->port, s, count, imx_uart_console_early_putchar);
}
static int __init
imx_console_early_setup(struct earlycon_device *dev, const char *opt)
{
if (!dev->port.membase)
return -ENODEV;
dev->con->write = imx_uart_console_early_write;
return 0;
}
OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup);
OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup);
MODULE_AUTHOR("NXP");
MODULE_DESCRIPTION("IMX earlycon driver");
MODULE_LICENSE("GPL");

View File

@ -16,7 +16,7 @@
#include "jsm.h"
MODULE_AUTHOR("Digi International, http://www.digi.com");
MODULE_AUTHOR("Digi International, https://www.digi.com");
MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("jsm");

View File

@ -538,7 +538,8 @@ static int __init kgdboc_earlycon_init(char *opt)
if (!con) {
/*
* Both earlycon and kgdboc_earlycon are initialized during * early parameter parsing. We cannot guarantee earlycon gets
* Both earlycon and kgdboc_earlycon are initialized during
* early parameter parsing. We cannot guarantee earlycon gets
* in first and, in any case, on ACPI systems earlycon may
* defer its own initialization (usually to somewhere within
* setup_arch() ). To cope with either of these situations

View File

@ -696,6 +696,7 @@ static void msm_enable_ms(struct uart_port *port)
}
static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
__must_hold(&port->lock)
{
struct tty_port *tport = &port->state->port;
unsigned int sr;
@ -771,6 +772,7 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
}
static void msm_handle_rx(struct uart_port *port)
__must_hold(&port->lock)
{
struct tty_port *tport = &port->state->port;
unsigned int sr;

View File

@ -1857,41 +1857,24 @@ static void pch_uart_pci_remove(struct pci_dev *pdev)
kfree(priv);
return;
}
#ifdef CONFIG_PM
static int pch_uart_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int __maybe_unused pch_uart_pci_suspend(struct device *dev)
{
struct eg20t_port *priv = pci_get_drvdata(pdev);
struct eg20t_port *priv = dev_get_drvdata(dev);
uart_suspend_port(&pch_uart_driver, &priv->port);
pci_save_state(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
static int pch_uart_pci_resume(struct pci_dev *pdev)
static int __maybe_unused pch_uart_pci_resume(struct device *dev)
{
struct eg20t_port *priv = pci_get_drvdata(pdev);
int ret;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
ret = pci_enable_device(pdev);
if (ret) {
dev_err(&pdev->dev,
"%s-pci_enable_device failed(ret=%d) ", __func__, ret);
return ret;
}
struct eg20t_port *priv = dev_get_drvdata(dev);
uart_resume_port(&pch_uart_driver, &priv->port);
return 0;
}
#else
#define pch_uart_pci_suspend NULL
#define pch_uart_pci_resume NULL
#endif
static const struct pci_device_id pch_uart_pci_id[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811),
@ -1945,13 +1928,16 @@ probe_error:
return ret;
}
static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops,
pch_uart_pci_suspend,
pch_uart_pci_resume);
static struct pci_driver pch_uart_pci_driver = {
.name = "pch_uart",
.id_table = pch_uart_pci_id,
.probe = pch_uart_pci_probe,
.remove = pch_uart_pci_remove,
.suspend = pch_uart_pci_suspend,
.resume = pch_uart_pci_resume,
.driver.pm = &pch_uart_pci_pm_ops,
};
static int __init pch_uart_module_init(void)

View File

@ -213,6 +213,7 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
}
static bool pmz_receive_chars(struct uart_pmac_port *uap)
__must_hold(&uap->port.lock)
{
struct tty_port *port;
unsigned char ch, r1, drop, flag;

View File

@ -768,7 +768,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
u8 buf[sizeof(u32)];
int c;
memset(buf, 0, ARRAY_SIZE(buf));
memset(buf, 0, sizeof(buf));
tx_bytes = min_t(size_t, remaining, BYTES_PER_FIFO_WORD);
for (c = 0; c < tx_bytes ; c++) {

View File

@ -6,7 +6,7 @@
* http://armlinux.simtec.co.uk/
*/
/* Hote on 2410 error handling
/* Note on 2410 error handling
*
* The s3c2410 manual has a love/hate affair with the contents of the
* UERSTAT register in the UART blocks, and keeps marking some of the
@ -327,7 +327,6 @@ static void s3c24xx_serial_tx_dma_complete(void *args)
unsigned long flags;
int count;
dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state);
count = dma->tx_bytes_requested - state.residue;
async_tx_ack(dma->tx_desc);
@ -409,7 +408,6 @@ static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport,
struct circ_buf *xmit = &port->state->xmit;
struct s3c24xx_uart_dma *dma = ourport->dma;
if (ourport->tx_mode != S3C24XX_TX_DMA)
enable_tx_dma(ourport);
@ -816,7 +814,6 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
return IRQ_HANDLED;
}
static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
{
struct s3c24xx_uart_port *ourport = dev_id;
@ -842,8 +839,8 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
count >= ourport->min_dma_size) {
int align = dma_get_cache_alignment() -
(xmit->tail & (dma_get_cache_alignment() - 1));
if (count-align >= ourport->min_dma_size) {
dma_count = count-align;
if (count - align >= ourport->min_dma_size) {
dma_count = count - align;
count = align;
}
}
@ -1589,7 +1586,6 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
return 0;
}
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
static struct console s3c24xx_serial_console;
@ -1672,7 +1668,6 @@ s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
}
},
#if CONFIG_SERIAL_SAMSUNG_UARTS > 2
[2] = {
.port = {
.lock = __PORT_LOCK_UNLOCKED(2),
@ -1728,7 +1723,6 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
udelay(1);
}
#ifdef CONFIG_ARM_S3C24XX_CPUFREQ
static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
@ -1903,9 +1897,9 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
port->mapbase = res->start;
ret = platform_get_irq(platdev, 0);
if (ret < 0)
if (ret < 0) {
port->irq = 0;
else {
} else {
port->irq = ret;
ourport->rx_irq = ret;
ourport->tx_irq = ret + 1;
@ -1977,8 +1971,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[];
static int probe_index;
static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data(
struct platform_device *pdev)
static inline struct s3c24xx_serial_drv_data *
s3c24xx_get_driver_data(struct platform_device *pdev)
{
#ifdef CONFIG_OF
if (pdev->dev.of_node) {
@ -2329,7 +2323,6 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
*baud = rate / (16 * (ubrdiv + 1));
dev_dbg(port->dev, "calculated baud %d\n", *baud);
}
}
static int __init
@ -2696,6 +2689,7 @@ static int __init s3c2410_early_console_setup(struct earlycon_device *device,
device->port.private_data = &s3c2410_early_console_data;
return samsung_early_console_setup(device, opt);
}
OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart",
s3c2410_early_console_setup);
@ -2710,6 +2704,7 @@ static int __init s3c2440_early_console_setup(struct earlycon_device *device,
device->port.private_data = &s3c2440_early_console_data;
return samsung_early_console_setup(device, opt);
}
OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart",
s3c2440_early_console_setup);
OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart",
@ -2728,6 +2723,7 @@ static int __init s5pv210_early_console_setup(struct earlycon_device *device,
device->port.private_data = &s5pv210_early_console_data;
return samsung_early_console_setup(device, opt);
}
OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
s5pv210_early_console_setup);
OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",

View File

@ -439,16 +439,16 @@ static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup,
/* Overrrun error */
flag = TTY_OVERRUN;
tup->uport.icount.overrun++;
dev_err(tup->uport.dev, "Got overrun errors\n");
dev_dbg(tup->uport.dev, "Got overrun errors\n");
} else if (lsr & UART_LSR_PE) {
/* Parity error */
flag = TTY_PARITY;
tup->uport.icount.parity++;
dev_err(tup->uport.dev, "Got Parity errors\n");
dev_dbg(tup->uport.dev, "Got Parity errors\n");
} else if (lsr & UART_LSR_FE) {
flag = TTY_FRAME;
tup->uport.icount.frame++;
dev_err(tup->uport.dev, "Got frame errors\n");
dev_dbg(tup->uport.dev, "Got frame errors\n");
} else if (lsr & UART_LSR_BI) {
/*
* Break error

View File

@ -14,6 +14,7 @@
#include <linux/sched/signal.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@ -1120,7 +1121,7 @@ out:
return ret;
}
static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
{
struct tty_port *port = &state->port;
struct uart_port *uport;
@ -1523,6 +1524,7 @@ static void uart_set_termios(struct tty_struct *tty,
/* Handle transition away from B0 status */
else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
unsigned int mask = TIOCM_DTR;
if (!(cflag & CRTSCTS) || !tty_throttled(tty))
mask |= TIOCM_RTS;
uart_set_mctrl(uport, mask);
@ -2279,6 +2281,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
if (console_suspend_enabled || !uart_console(uport)) {
/* Protected by port mutex for now */
struct tty_struct *tty = port->tty;
ret = ops->startup(uport);
if (ret == 0) {
if (tty)

View File

@ -3301,9 +3301,6 @@ static int sci_probe_single(struct platform_device *dev,
sciport->port.flags |= UPF_HARD_FLOW;
}
if (sci_uart_driver.cons->index == sciport->port.line)
spin_lock_init(&sciport->port.lock);
ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
if (ret) {
sci_cleanup_single(sciport);

View File

@ -883,7 +883,6 @@ console_initcall(sifive_console_init);
static void __ssp_add_console_port(struct sifive_serial_port *ssp)
{
spin_lock_init(&ssp->port.lock);
sifive_serial_console_ports[ssp->port.line] = ssp;
}

View File

@ -129,9 +129,13 @@ static int stm32_config_rs485(struct uart_port *port,
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
cr3 &= ~USART_CR3_DEP;
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
mctrl_gpio_set(stm32_port->gpios,
stm32_port->port.mctrl & ~TIOCM_RTS);
} else {
cr3 |= USART_CR3_DEP;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
mctrl_gpio_set(stm32_port->gpios,
stm32_port->port.mctrl | TIOCM_RTS);
}
writel_relaxed(cr3, port->membase + ofs->cr3);
@ -847,9 +851,13 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
cr3 &= ~USART_CR3_DEP;
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
mctrl_gpio_set(stm32_port->gpios,
stm32_port->port.mctrl & ~TIOCM_RTS);
} else {
cr3 |= USART_CR3_DEP;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
mctrl_gpio_set(stm32_port->gpios,
stm32_port->port.mctrl | TIOCM_RTS);
}
} else {
@ -1033,8 +1041,9 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
if (WARN_ON(id >= STM32_MAX_PORTS))
return NULL;
stm32_ports[id].hw_flow_control = of_property_read_bool(np,
"st,hw-flow-ctrl");
stm32_ports[id].hw_flow_control =
of_property_read_bool (np, "st,hw-flow-ctrl") /*deprecated*/ ||
of_property_read_bool (np, "uart-has-rtscts");
stm32_ports[id].port.line = id;
stm32_ports[id].cr1_irq = USART_CR1_RXNEIE;
stm32_ports[id].cr3_irq = 0;

View File

@ -567,9 +567,6 @@ static int hv_probe(struct platform_device *op)
sunserial_console_match(&sunhv_console, op->dev.of_node,
&sunhv_reg, port->line, false);
/* We need to initialize lock even for non-registered console */
spin_lock_init(&port->lock);
err = uart_add_one_port(&sunhv_reg, port);
if (err)
goto out_unregister_driver;

View File

@ -32,7 +32,7 @@
* Register definitions
*
* For register details see datasheet:
* http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
* https://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
*/
#define ULITE_RX 0x00

View File

@ -252,7 +252,6 @@ struct mgsl_struct {
char device_name[25]; /* device instance name */
unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */
unsigned char bus; /* expansion bus number (zero based) */
unsigned char function; /* PCI device number */
@ -3432,15 +3431,9 @@ static inline void line_info(struct seq_file *m, struct mgsl_struct *info)
char stat_buf[30];
unsigned long flags;
if (info->bus_type == MGSL_BUS_TYPE_PCI) {
seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base);
} else {
seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
info->device_name, info->io_base,
info->irq_level, info->dma_level);
}
seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base);
/* output current serial signal states */
spin_lock_irqsave(&info->irq_spinlock,flags);
@ -3556,54 +3549,27 @@ static int mgsl_allocate_dma_buffers(struct mgsl_struct *info)
if ( info->max_frame_size % DMABUFFERSIZE )
BuffersPerFrame++;
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
/*
* The PCI adapter has 256KBytes of shared memory to use.
* This is 64 PAGE_SIZE buffers.
*
* The first page is used for padding at this time so the
* buffer list does not begin at offset 0 of the PCI
* adapter's shared memory.
*
* The 2nd page is used for the buffer list. A 4K buffer
* list can hold 128 DMA_BUFFER structures at 32 bytes
* each.
*
* This leaves 62 4K pages.
*
* The next N pages are used for transmit frame(s). We
* reserve enough 4K page blocks to hold the required
* number of transmit dma buffers (num_tx_dma_buffers),
* each of MaxFrameSize size.
*
* Of the remaining pages (62-N), determine how many can
* be used to receive full MaxFrameSize inbound frames
*/
info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
info->rx_buffer_count = 62 - info->tx_buffer_count;
} else {
/* Calculate the number of PAGE_SIZE buffers needed for */
/* receive and transmit DMA buffers. */
/* Calculate the number of DMA buffers necessary to */
/* hold 7 max size receive frames and one max size transmit frame. */
/* The receive buffer count is bumped by one so we avoid an */
/* End of List condition if all receive buffers are used when */
/* using linked list DMA buffers. */
info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
info->rx_buffer_count = (BuffersPerFrame * MAXRXFRAMES) + 6;
/*
* limit total TxBuffers & RxBuffers to 62 4K total
* (ala PCI Allocation)
*/
if ( (info->tx_buffer_count + info->rx_buffer_count) > 62 )
info->rx_buffer_count = 62 - info->tx_buffer_count;
}
/*
* The PCI adapter has 256KBytes of shared memory to use. This is 64
* PAGE_SIZE buffers.
*
* The first page is used for padding at this time so the buffer list
* does not begin at offset 0 of the PCI adapter's shared memory.
*
* The 2nd page is used for the buffer list. A 4K buffer list can hold
* 128 DMA_BUFFER structures at 32 bytes each.
*
* This leaves 62 4K pages.
*
* The next N pages are used for transmit frame(s). We reserve enough
* 4K page blocks to hold the required number of transmit dma buffers
* (num_tx_dma_buffers), each of MaxFrameSize size.
*
* Of the remaining pages (62-N), determine how many can be used to
* receive full MaxFrameSize inbound frames
*/
info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
info->rx_buffer_count = 62 - info->tx_buffer_count;
if ( debug_level >= DEBUG_LEVEL_INFO )
printk("%s(%d):Allocating %d TX and %d RX DMA buffers.\n",
@ -3652,23 +3618,10 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
{
unsigned int i;
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
/* PCI adapter uses shared memory. */
info->buffer_list = info->memory_base + info->last_mem_alloc;
info->buffer_list_phys = info->last_mem_alloc;
info->last_mem_alloc += BUFFERLISTSIZE;
} else {
/* ISA adapter uses system memory. */
/* The buffer lists are allocated as a common buffer that both */
/* the processor and adapter can access. This allows the driver to */
/* inspect portions of the buffer while other portions are being */
/* updated by the adapter using Bus Master DMA. */
info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL);
if (info->buffer_list == NULL)
return -ENOMEM;
info->buffer_list_phys = (u32)(info->buffer_list_dma_addr);
}
/* PCI adapter uses shared memory. */
info->buffer_list = info->memory_base + info->last_mem_alloc;
info->buffer_list_phys = info->last_mem_alloc;
info->last_mem_alloc += BUFFERLISTSIZE;
/* We got the memory for the buffer entry lists. */
/* Initialize the memory block to all zeros. */
@ -3734,9 +3687,6 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
*/
static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
{
if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI)
dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr);
info->buffer_list = NULL;
info->rx_buffer_list = NULL;
info->tx_buffer_list = NULL;
@ -3762,24 +3712,13 @@ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
{
int i;
u32 phys_addr;
/* Allocate page sized buffers for the receive buffer list */
for ( i = 0; i < Buffercount; i++ ) {
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
/* PCI adapter uses shared memory buffers. */
BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc;
phys_addr = info->last_mem_alloc;
info->last_mem_alloc += DMABUFFERSIZE;
} else {
/* ISA adapter uses system memory. */
BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL);
if (BufferList[i].virt_addr == NULL)
return -ENOMEM;
phys_addr = (u32)(BufferList[i].dma_addr);
}
BufferList[i].phys_addr = phys_addr;
BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc;
BufferList[i].phys_addr = info->last_mem_alloc;
info->last_mem_alloc += DMABUFFERSIZE;
}
return 0;
@ -3807,8 +3746,6 @@ static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *Buf
if ( BufferList ) {
for ( i = 0 ; i < Buffercount ; i++ ) {
if ( BufferList[i].virt_addr ) {
if ( info->bus_type != MGSL_BUS_TYPE_PCI )
dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr);
BufferList[i].virt_addr = NULL;
}
}
@ -4040,58 +3977,40 @@ static int mgsl_claim_resources(struct mgsl_struct *info)
}
info->irq_requested = true;
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) {
printk( "%s(%d):mem addr conflict device %s Addr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base);
goto errout;
}
info->shared_mem_requested = true;
if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) {
printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset);
goto errout;
}
info->lcr_mem_requested = true;
info->memory_base = ioremap(info->phys_memory_base,
0x40000);
if (!info->memory_base) {
printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
goto errout;
}
if ( !mgsl_memory_test(info) ) {
printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
goto errout;
}
info->lcr_base = ioremap(info->phys_lcr_base,
PAGE_SIZE);
if (!info->lcr_base) {
printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base );
goto errout;
}
info->lcr_base += info->lcr_offset;
} else {
/* claim DMA channel */
if (request_dma(info->dma_level,info->device_name) < 0){
printk( "%s(%d):Can't request DMA channel on device %s DMA=%d\n",
__FILE__,__LINE__,info->device_name, info->dma_level );
goto errout;
}
info->dma_requested = true;
/* ISA adapter uses bus master DMA */
set_dma_mode(info->dma_level,DMA_MODE_CASCADE);
enable_dma(info->dma_level);
if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) {
printk( "%s(%d):mem addr conflict device %s Addr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base);
goto errout;
}
info->shared_mem_requested = true;
if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) {
printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset);
goto errout;
}
info->lcr_mem_requested = true;
info->memory_base = ioremap(info->phys_memory_base, 0x40000);
if (!info->memory_base) {
printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
goto errout;
}
if ( !mgsl_memory_test(info) ) {
printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
goto errout;
}
info->lcr_base = ioremap(info->phys_lcr_base, PAGE_SIZE);
if (!info->lcr_base) {
printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base );
goto errout;
}
info->lcr_base += info->lcr_offset;
if ( mgsl_allocate_dma_buffers(info) < 0 ) {
printk( "%s(%d):Can't allocate DMA buffers on device %s DMA=%d\n",
__FILE__,__LINE__,info->device_name, info->dma_level );
@ -4200,16 +4119,10 @@ static void mgsl_add_device( struct mgsl_struct *info )
else if ( info->max_frame_size > 65535 )
info->max_frame_size = 65535;
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n",
info->hw_version + 1, info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base,
info->max_frame_size );
} else {
printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n",
info->device_name, info->io_base, info->irq_level, info->dma_level,
info->max_frame_size );
}
printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n",
info->hw_version + 1, info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base,
info->max_frame_size );
#if SYNCLINK_GENERIC_HDLC
hdlcdev_init(info);
@ -4420,8 +4333,7 @@ static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd )
outw( Cmd + info->loopback_bits, info->io_base + CCAR );
/* Read to flush write to CCAR */
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
inw( info->io_base + CCAR );
inw( info->io_base + CCAR );
} /* end of usc_RTCmd() */
@ -4445,8 +4357,7 @@ static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd )
outw( Cmd + info->mbre_bit, info->io_base );
/* Read to flush write to DCAR */
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
inw( info->io_base );
inw( info->io_base );
} /* end of usc_DmaCmd() */
@ -4475,8 +4386,7 @@ static void usc_OutDmaReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue )
outw( RegValue, info->io_base );
/* Read to flush write to DCAR */
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
inw( info->io_base );
inw( info->io_base );
} /* end of usc_OutDmaReg() */
@ -4528,8 +4438,7 @@ static void usc_OutReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue )
outw( RegValue, info->io_base + CCAR );
/* Read to flush write to CCAR */
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
inw( info->io_base + CCAR );
inw( info->io_base + CCAR );
} /* end of usc_OutReg() */
@ -4728,10 +4637,7 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info )
RegValue = usc_InReg( info, RICR ) & 0xc0;
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
usc_OutReg( info, RICR, (u16)(0x030a | RegValue) );
else
usc_OutReg( info, RICR, (u16)(0x140a | RegValue) );
usc_OutReg( info, RICR, (u16)(0x030a | RegValue) );
/* Unlatch all Rx status bits and clear Rx status IRQ Pending */
@ -4792,10 +4698,7 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info )
* 0000 0000 0011 0110 = 0x0036
*/
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
usc_OutReg( info, TICR, 0x0736 );
else
usc_OutReg( info, TICR, 0x1436 );
usc_OutReg( info, TICR, 0x0736 );
usc_UnlatchTxstatusBits( info, TXSTATUS_ALL );
usc_ClearIrqPendingBits( info, TRANSMIT_STATUS );
@ -4885,10 +4788,7 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info )
/* DPLL is enabled. Use BRG1 to provide continuous reference clock */
/* for DPLL. DPLL mode in HCR is dependent on the encoding used. */
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
XtalSpeed = 11059200;
else
XtalSpeed = 14745600;
XtalSpeed = 11059200;
if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) {
DpllDivisor = 16;
@ -5011,13 +4911,8 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info )
* 0110 0000 0000 1011 = 0x600b
*/
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
/* PCI adapter does not need DMA wait state */
usc_OutDmaReg( info, DCR, 0xa00b );
}
else
usc_OutDmaReg( info, DCR, 0x800b );
/* PCI adapter does not need DMA wait state */
usc_OutDmaReg( info, DCR, 0xa00b );
/* Receive DMA mode Register (RDMR)
*
@ -5109,12 +5004,8 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info )
* <7..0> 0x00 Maximum number of clock cycles per bus grant
*/
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
/* don't limit bus occupancy on PCI adapter */
usc_OutDmaReg( info, BDCR, 0x0000 );
}
else
usc_OutDmaReg( info, BDCR, 0x2000 );
/* don't limit bus occupancy on PCI adapter */
usc_OutDmaReg( info, BDCR, 0x0000 );
usc_stop_transmitter(info);
usc_stop_receiver(info);
@ -5155,10 +5046,7 @@ static void usc_enable_loopback(struct mgsl_struct *info, int enable)
/* Write 16-bit Time Constant for BRG0 */
/* use clock speed if available, otherwise use 8 for diagnostics */
if (info->params.clock_speed) {
if (info->bus_type == MGSL_BUS_TYPE_PCI)
usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1));
else
usc_OutReg(info, TC0R, (u16)((14745600/info->params.clock_speed)-1));
usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1));
} else
usc_OutReg(info, TC0R, (u16)8);
@ -5201,10 +5089,7 @@ static void usc_enable_aux_clock( struct mgsl_struct *info, u32 data_rate )
u16 Tc;
if ( data_rate ) {
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
XtalSpeed = 11059200;
else
XtalSpeed = 14745600;
XtalSpeed = 11059200;
/* Tc = (Xtal/Speed) - 1 */
@ -5682,44 +5567,38 @@ static void usc_load_txfifo( struct mgsl_struct *info )
*/
static void usc_reset( struct mgsl_struct *info )
{
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
int i;
u32 readval;
int i;
u32 readval;
/* Set BIT30 of Misc Control Register */
/* (Local Control Register 0x50) to force reset of USC. */
/* Set BIT30 of Misc Control Register */
/* (Local Control Register 0x50) to force reset of USC. */
volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28);
volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28);
info->misc_ctrl_value |= BIT30;
*MiscCtrl = info->misc_ctrl_value;
info->misc_ctrl_value |= BIT30;
*MiscCtrl = info->misc_ctrl_value;
/*
* Force at least 170ns delay before clearing
* reset bit. Each read from LCR takes at least
* 30ns so 10 times for 300ns to be safe.
*/
for(i=0;i<10;i++)
readval = *MiscCtrl;
/*
* Force at least 170ns delay before clearing reset bit. Each read from
* LCR takes at least 30ns so 10 times for 300ns to be safe.
*/
for(i=0;i<10;i++)
readval = *MiscCtrl;
info->misc_ctrl_value &= ~BIT30;
*MiscCtrl = info->misc_ctrl_value;
info->misc_ctrl_value &= ~BIT30;
*MiscCtrl = info->misc_ctrl_value;
*LCR0BRDR = BUS_DESCRIPTOR(
1, // Write Strobe Hold (0-3)
2, // Write Strobe Delay (0-3)
2, // Read Strobe Delay (0-3)
0, // NWDD (Write data-data) (0-3)
4, // NWAD (Write Addr-data) (0-31)
0, // NXDA (Read/Write Data-Addr) (0-3)
0, // NRDD (Read Data-Data) (0-3)
5 // NRAD (Read Addr-Data) (0-31)
);
} else {
/* do HW reset */
outb( 0,info->io_base + 8 );
}
*LCR0BRDR = BUS_DESCRIPTOR(
1, // Write Strobe Hold (0-3)
2, // Write Strobe Delay (0-3)
2, // Read Strobe Delay (0-3)
0, // NWDD (Write data-data) (0-3)
4, // NWAD (Write Addr-data) (0-31)
0, // NXDA (Read/Write Data-Addr) (0-3)
0, // NRDD (Read Data-Data) (0-3)
5 // NRAD (Read Addr-Data) (0-31)
);
info->mbre_bit = 0;
info->loopback_bits = 0;
@ -6228,11 +6107,7 @@ static void usc_enable_async_clock( struct mgsl_struct *info, u32 data_rate )
* ClkSpeed = 921600 (ISA), 691200 (PCI)
*/
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) );
else
usc_OutReg( info, TC0R, (u16)((921600/data_rate) - 1) );
usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) );
/*
* Hardware Configuration Register (HCR)
@ -6837,10 +6712,7 @@ static void mgsl_load_tx_dma_buffer(struct mgsl_struct *info,
/* Actually copy data from source buffer to DMA buffer. */
/* Also set the data count for this individual DMA buffer. */
if ( info->bus_type == MGSL_BUS_TYPE_PCI )
mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount);
else
memcpy(pBufEntry->virt_addr, Buffer, Copycount);
mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount);
pBufEntry->count = Copycount;
@ -7315,9 +7187,6 @@ static bool mgsl_memory_test( struct mgsl_struct *info )
unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long);
unsigned long * TestAddr;
if ( info->bus_type != MGSL_BUS_TYPE_PCI )
return true;
TestAddr = (unsigned long *)info->memory_base;
/* Test data lines with test pattern at one location. */
@ -8003,7 +7872,6 @@ static int synclink_init_one (struct pci_dev *dev,
info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1);
info->phys_lcr_base &= ~(PAGE_SIZE-1);
info->bus_type = MGSL_BUS_TYPE_PCI;
info->io_addr_size = 8;
info->irq_flags = IRQF_SHARED;

View File

@ -1405,7 +1405,7 @@ void tty_save_termios(struct tty_struct *tty)
/* Stash the termios data */
tp = tty->driver->termios[idx];
if (tp == NULL) {
tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
tp = kmalloc(sizeof(*tp), GFP_KERNEL);
if (tp == NULL)
return;
tty->driver->termios[idx] = tp;
@ -2489,7 +2489,7 @@ static int tty_tiocsserial(struct tty_struct *tty, struct serial_struct __user *
struct serial_struct v;
int flags;
if (copy_from_user(&v, ss, sizeof(struct serial_struct)))
if (copy_from_user(&v, ss, sizeof(*ss)))
return -EFAULT;
flags = v.flags & ASYNC_DEPRECATED;
@ -2507,11 +2507,11 @@ static int tty_tiocgserial(struct tty_struct *tty, struct serial_struct __user *
struct serial_struct v;
int err;
memset(&v, 0, sizeof(struct serial_struct));
memset(&v, 0, sizeof(v));
if (!tty->ops->get_serial)
return -ENOTTY;
err = tty->ops->get_serial(tty, &v);
if (!err && copy_to_user(ss, &v, sizeof(struct serial_struct)))
if (!err && copy_to_user(ss, &v, sizeof(v)))
err = -EFAULT;
return err;
}
@ -2673,25 +2673,25 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#ifdef CONFIG_COMPAT
struct serial_struct32 {
compat_int_t type;
compat_int_t line;
compat_uint_t port;
compat_int_t irq;
compat_int_t flags;
compat_int_t xmit_fifo_size;
compat_int_t custom_divisor;
compat_int_t baud_base;
unsigned short close_delay;
char io_type;
char reserved_char[1];
compat_int_t hub6;
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
compat_uint_t iomem_base;
unsigned short iomem_reg_shift;
unsigned int port_high;
/* compat_ulong_t iomap_base FIXME */
compat_int_t reserved[1];
compat_int_t type;
compat_int_t line;
compat_uint_t port;
compat_int_t irq;
compat_int_t flags;
compat_int_t xmit_fifo_size;
compat_int_t custom_divisor;
compat_int_t baud_base;
unsigned short close_delay;
char io_type;
char reserved_char;
compat_int_t hub6;
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
compat_uint_t iomem_base;
unsigned short iomem_reg_shift;
unsigned int port_high;
/* compat_ulong_t iomap_base FIXME */
compat_int_t reserved;
};
static int compat_tty_tiocsserial(struct tty_struct *tty,
@ -2705,7 +2705,7 @@ static int compat_tty_tiocsserial(struct tty_struct *tty,
struct serial_struct v;
int flags;
if (copy_from_user(&v32, ss, sizeof(struct serial_struct32)))
if (copy_from_user(&v32, ss, sizeof(*ss)))
return -EFAULT;
memcpy(&v, &v32, offsetof(struct serial_struct32, iomem_base));
@ -2743,7 +2743,7 @@ static int compat_tty_tiocgserial(struct tty_struct *tty,
0xfffffff : ptr_to_compat(v.iomem_base);
v32.iomem_reg_shift = v.iomem_reg_shift;
v32.port_high = v.port_high;
if (copy_to_user(ss, &v32, sizeof(struct serial_struct32)))
if (copy_to_user(ss, &v32, sizeof(v32)))
err = -EFAULT;
}
return err;
@ -3215,7 +3215,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner,
if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1))
return ERR_PTR(-EINVAL);
driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
driver = kzalloc(sizeof(*driver), GFP_KERNEL);
if (!driver)
return ERR_PTR(-ENOMEM);

View File

@ -542,7 +542,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
if (!ct)
return 0;
unilist = vmemdup_user(list, ct * sizeof(struct unipair));
unilist = vmemdup_user(list, array_size(sizeof(struct unipair), ct));
if (IS_ERR(unilist))
return PTR_ERR(unilist);

View File

@ -32,6 +32,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/mm.h>
#include <linux/nospec.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/slab.h>
@ -2019,7 +2020,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
goto reterr;
}
kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
i = kbs->kb_func;
i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
switch (cmd) {
case KDGKBSENT:

View File

@ -193,7 +193,7 @@ static int vc_selection_store_chars(struct vc_data *vc, bool unicode)
/* Allocate a new buffer before freeing the old one ... */
/* chars can take up to 4 bytes with unicode */
bp = kmalloc_array((vc_sel.end - vc_sel.start) / 2 + 1, unicode ? 4 : 1,
GFP_KERNEL);
GFP_KERNEL | __GFP_NOWARN);
if (!bp) {
printk(KERN_WARNING "selection: kmalloc() failed\n");
clear_selection();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -302,14 +302,15 @@ sisusbcon_deinit(struct vc_data *c)
/* interface routine */
static u8
sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse, u8 unused)
sisusbcon_build_attr(struct vc_data *c, u8 color, enum vc_intensity intensity,
bool blink, bool underline, bool reverse,
bool unused)
{
u8 attr = color;
if (underline)
attr = (attr & 0xf0) | c->vc_ulcolor;
else if (intensity == 0)
else if (intensity == VCI_HALF_BRIGHT)
attr = (attr & 0xf0) | c->vc_halfcolor;
if (reverse)
@ -320,7 +321,7 @@ sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
if (blink)
attr ^= 0x80;
if (intensity == 2)
if (intensity == VCI_BOLD)
attr ^= 0x08;
return attr;
@ -726,7 +727,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2);
switch (c->vc_cursor_type & 0x0f) {
switch (CUR_SIZE(c->vc_cursor_type)) {
case CUR_BLOCK: from = 1;
to = c->vc_font.height;
break;

View File

@ -394,8 +394,10 @@ static inline u16 mda_convert_attr(u16 ch)
(ch & 0x00ff) | attr;
}
static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse, u8 italic)
static u8 mdacon_build_attr(struct vc_data *c, u8 color,
enum vc_intensity intensity,
bool blink, bool underline, bool reverse,
bool italic)
{
/* The attribute is just a bit vector:
*
@ -405,11 +407,11 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
* Bit 7 : blink
*/
return (intensity & 3) |
((underline & 1) << 2) |
((reverse & 1) << 3) |
(!!italic << 4) |
((blink & 1) << 7);
return (intensity & VCI_MASK) |
(underline << 2) |
(reverse << 3) |
(italic << 4) |
(blink << 7);
}
static void mdacon_invert_region(struct vc_data *c, u16 *p, int count)
@ -488,9 +490,9 @@ static void mdacon_cursor(struct vc_data *c, int mode)
return;
}
mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2);
mda_set_cursor(c->state.y * mda_num_columns * 2 + c->state.x * 2);
switch (c->vc_cursor_type & 0x0f) {
switch (CUR_SIZE(c->vc_cursor_type)) {
case CUR_LOWER_THIRD: mda_set_cursor_size(10, 13); break;
case CUR_LOWER_HALF: mda_set_cursor_size(7, 13); break;

View File

@ -362,12 +362,12 @@ static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
if (ystart < yend) {
newport_clear_screen(sx << 3, ystart, xend, yend,
(vc->vc_color & 0xf0) >> 4);
(vc->state.color & 0xf0) >> 4);
} else {
newport_clear_screen(sx << 3, ystart, xend, 1023,
(vc->vc_color & 0xf0) >> 4);
(vc->state.color & 0xf0) >> 4);
newport_clear_screen(sx << 3, 0, xend, yend,
(vc->vc_color & 0xf0) >> 4);
(vc->state.color & 0xf0) >> 4);
}
}
@ -591,11 +591,11 @@ static bool newport_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
topscan = (topscan + (lines << 4)) & 0x3ff;
newport_clear_lines(vc->vc_rows - lines,
vc->vc_rows - 1,
(vc->vc_color & 0xf0) >> 4);
(vc->state.color & 0xf0) >> 4);
} else {
topscan = (topscan + (-lines << 4)) & 0x3ff;
newport_clear_lines(0, lines - 1,
(vc->vc_color & 0xf0) >> 4);
(vc->state.color & 0xf0) >> 4);
}
npregs->cset.topscan = (topscan - 1) & 0x3ff;
return false;

View File

@ -132,21 +132,21 @@ static void sticon_cursor(struct vc_data *conp, int mode)
{
unsigned short car1;
car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols];
car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols];
switch (mode) {
case CM_ERASE:
sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x);
sti_putc(sticon_sti, car1, conp->state.y, conp->state.x);
break;
case CM_MOVE:
case CM_DRAW:
switch (conp->vc_cursor_type & 0x0f) {
switch (CUR_SIZE(conp->vc_cursor_type)) {
case CUR_UNDERLINE:
case CUR_LOWER_THIRD:
case CUR_LOWER_HALF:
case CUR_TWO_THIRDS:
case CUR_BLOCK:
sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
conp->vc_y, conp->vc_x);
conp->state.y, conp->state.x);
break;
}
break;
@ -288,8 +288,10 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
return ret;
}
static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
u8 blink, u8 underline, u8 reverse, u8 italic)
static u8 sticon_build_attr(struct vc_data *conp, u8 color,
enum vc_intensity intens,
bool blink, bool underline, bool reverse,
bool italic)
{
u8 attr = ((color & 0x70) >> 1) | ((color & 7));

View File

@ -251,6 +251,10 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
p = (void *) (c->vc_origin + t * c->vc_size_row);
while (count--) {
if ((vgacon_scrollback_cur->tail + c->vc_size_row) >
vgacon_scrollback_cur->size)
vgacon_scrollback_cur->tail = 0;
scr_memcpyw(vgacon_scrollback_cur->data +
vgacon_scrollback_cur->tail,
p, c->vc_size_row);
@ -629,8 +633,10 @@ static void vgacon_deinit(struct vc_data *c)
con_set_default_unimap(c);
}
static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse, u8 italic)
static u8 vgacon_build_attr(struct vc_data *c, u8 color,
enum vc_intensity intensity,
bool blink, bool underline, bool reverse,
bool italic)
{
u8 attr = color;
@ -639,7 +645,7 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
attr = (attr & 0xF0) | c->vc_itcolor;
else if (underline)
attr = (attr & 0xf0) | c->vc_ulcolor;
else if (intensity == 0)
else if (intensity == VCI_HALF_BRIGHT)
attr = (attr & 0xf0) | c->vc_halfcolor;
}
if (reverse)
@ -648,14 +654,14 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
0x77);
if (blink)
attr ^= 0x80;
if (intensity == 2)
if (intensity == VCI_BOLD)
attr ^= 0x08;
if (!vga_can_do_color) {
if (italic)
attr = (attr & 0xF8) | 0x02;
else if (underline)
attr = (attr & 0xf8) | 0x01;
else if (intensity == 0)
else if (intensity == VCI_HALF_BRIGHT)
attr = (attr & 0xf0) | 0x08;
}
return attr;
@ -718,17 +724,17 @@ static void vgacon_cursor(struct vc_data *c, int mode)
case CM_ERASE:
write_vga(14, (c->vc_pos - vga_vram_base) / 2);
if (vga_video_type >= VIDEO_TYPE_VGAC)
vgacon_set_cursor_size(c->vc_x, 31, 30);
vgacon_set_cursor_size(c->state.x, 31, 30);
else
vgacon_set_cursor_size(c->vc_x, 31, 31);
vgacon_set_cursor_size(c->state.x, 31, 31);
break;
case CM_MOVE:
case CM_DRAW:
write_vga(14, (c->vc_pos - vga_vram_base) / 2);
switch (c->vc_cursor_type & 0x0f) {
switch (CUR_SIZE(c->vc_cursor_type)) {
case CUR_UNDERLINE:
vgacon_set_cursor_size(c->vc_x,
vgacon_set_cursor_size(c->state.x,
c->vc_font.height -
(c->vc_font.height <
10 ? 2 : 3),
@ -737,21 +743,21 @@ static void vgacon_cursor(struct vc_data *c, int mode)
10 ? 1 : 2));
break;
case CUR_TWO_THIRDS:
vgacon_set_cursor_size(c->vc_x,
vgacon_set_cursor_size(c->state.x,
c->vc_font.height / 3,
c->vc_font.height -
(c->vc_font.height <
10 ? 1 : 2));
break;
case CUR_LOWER_THIRD:
vgacon_set_cursor_size(c->vc_x,
vgacon_set_cursor_size(c->state.x,
(c->vc_font.height * 2) / 3,
c->vc_font.height -
(c->vc_font.height <
10 ? 1 : 2));
break;
case CUR_LOWER_HALF:
vgacon_set_cursor_size(c->vc_x,
vgacon_set_cursor_size(c->state.x,
c->vc_font.height / 2,
c->vc_font.height -
(c->vc_font.height <
@ -759,12 +765,12 @@ static void vgacon_cursor(struct vc_data *c, int mode)
break;
case CUR_NONE:
if (vga_video_type >= VIDEO_TYPE_VGAC)
vgacon_set_cursor_size(c->vc_x, 31, 30);
vgacon_set_cursor_size(c->state.x, 31, 30);
else
vgacon_set_cursor_size(c->vc_x, 31, 31);
vgacon_set_cursor_size(c->state.x, 31, 31);
break;
default:
vgacon_set_cursor_size(c->vc_x, 1,
vgacon_set_cursor_size(c->state.x, 1,
c->vc_font.height);
break;
}
@ -1352,8 +1358,8 @@ static void vgacon_save_screen(struct vc_data *c)
* console initialization routines.
*/
vga_bootup_console = 1;
c->vc_x = screen_info.orig_x;
c->vc_y = screen_info.orig_y;
c->state.x = screen_info.orig_x;
c->state.y = screen_info.orig_y;
}
/* We can't copy in more than the size of the video buffer,

View File

@ -240,8 +240,8 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int y = real_y(ops->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1;
char *src;
@ -286,10 +286,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
cursor.set |= FB_CUR_SETCMAP;
}
if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->vc_x)) ||
if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) ||
(ops->cursor_state.image.dy != (vc->vc_font.height * y)) ||
ops->cursor_reset) {
ops->cursor_state.image.dx = vc->vc_font.width * vc->vc_x;
ops->cursor_state.image.dx = vc->vc_font.width * vc->state.x;
ops->cursor_state.image.dy = vc->vc_font.height * y;
cursor.set |= FB_CUR_SETPOS;
}
@ -325,7 +325,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
switch (CUR_SIZE(ops->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;

View File

@ -655,11 +655,11 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
}
if (!save) {
int lines;
if (vc->vc_y + logo_lines >= rows)
lines = rows - vc->vc_y - 1;
if (vc->state.y + logo_lines >= rows)
lines = rows - vc->state.y - 1;
else
lines = logo_lines;
vc->vc_y += lines;
vc->state.y += lines;
vc->vc_pos += lines * vc->vc_size_row;
}
}
@ -677,7 +677,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
vc->vc_size_row *
rows);
scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2));
vc->vc_y += logo_lines;
vc->state.y += logo_lines;
vc->vc_pos += logo_lines * vc->vc_size_row;
kfree(save);
}
@ -1393,7 +1393,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
return;
if (vc->vc_cursor_type & 0x10)
if (vc->vc_cursor_type & CUR_SW)
fbcon_del_cursor_timer(info);
else
fbcon_add_cursor_timer(info);

View File

@ -225,8 +225,8 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.height + 7) >> 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int y = real_y(ops->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
char *src;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
@ -284,7 +284,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
dx = y * vc->vc_font.height;
dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
dy = vyres - ((vc->state.x + 1) * vc->vc_font.width);
if (ops->cursor_state.image.dx != dx ||
ops->cursor_state.image.dy != dy ||
@ -325,7 +325,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
switch (CUR_SIZE(ops->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;

View File

@ -208,8 +208,8 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.height + 7) >> 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int y = real_y(ops->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
char *src;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
@ -267,7 +267,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
dy = vc->vc_x * vc->vc_font.width;
dy = vc->state.x * vc->vc_font.width;
if (ops->cursor_state.image.dx != dx ||
ops->cursor_state.image.dy != dy ||
@ -308,7 +308,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
switch (CUR_SIZE(ops->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;

View File

@ -255,8 +255,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int y = real_y(ops->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
char *src;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
@ -315,7 +315,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
dx = vxres - ((vc->state.x * vc->vc_font.width) + vc->vc_font.width);
if (ops->cursor_state.image.dx != dx ||
ops->cursor_state.image.dy != dy ||
@ -348,7 +348,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
switch (CUR_SIZE(ops->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;

View File

@ -83,10 +83,10 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_tilecursor cursor;
int use_sw = (vc->vc_cursor_type & 0x10);
int use_sw = vc->vc_cursor_type & CUR_SW;
cursor.sx = vc->vc_x;
cursor.sy = vc->vc_y;
cursor.sx = vc->state.x;
cursor.sy = vc->state.y;
cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
cursor.fg = fg;
cursor.bg = bg;

View File

@ -24,17 +24,13 @@ struct module;
struct tty_struct;
struct notifier_block;
/*
* this is what the terminal answers to a ESC-Z or csi0c query.
*/
#define VT100ID "\033[?1;2c"
#define VT102ID "\033[?6c"
enum con_scroll {
SM_UP,
SM_DOWN,
};
enum vc_intensity;
/**
* struct consw - callbacks for consoles
*
@ -74,8 +70,9 @@ struct consw {
void (*con_scrolldelta)(struct vc_data *vc, int lines);
int (*con_set_origin)(struct vc_data *vc);
void (*con_save_screen)(struct vc_data *vc);
u8 (*con_build_attr)(struct vc_data *vc, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse, u8 italic);
u8 (*con_build_attr)(struct vc_data *vc, u8 color,
enum vc_intensity intensity,
bool blink, bool underline, bool reverse, bool italic);
void (*con_invert_region)(struct vc_data *vc, u16 *p, int count);
u16 *(*con_screen_pos)(struct vc_data *vc, int offset);
unsigned long (*con_getxy)(struct vc_data *vc, unsigned long position,

View File

@ -21,6 +21,43 @@ struct uni_pagedir;
struct uni_screen;
#define NPAR 16
#define VC_TABSTOPS_COUNT 256U
enum vc_intensity {
VCI_HALF_BRIGHT,
VCI_NORMAL,
VCI_BOLD,
VCI_MASK = 0x3,
};
/**
* struct vc_state -- state of a VC
* @x: cursor's x-position
* @y: cursor's y-position
* @color: foreground & background colors
* @Gx_charset: what's G0/G1 slot set to (like GRAF_MAP, LAT1_MAP)
* @charset: what character set to use (0=G0 or 1=G1)
* @intensity: see enum vc_intensity for values
* @reverse: reversed foreground/background colors
*
* These members are defined separately from struct vc_data as we save &
* restore them at times.
*/
struct vc_state {
unsigned int x, y;
unsigned char color;
unsigned char Gx_charset[2];
unsigned int charset : 1;
/* attribute flags */
enum vc_intensity intensity;
bool italic;
bool underline;
bool blink;
bool reverse;
};
/*
* Example: vc_data of a console that was scrolled 3 lines down.
@ -57,6 +94,8 @@ struct uni_screen;
struct vc_data {
struct tty_port port; /* Upper level data */
struct vc_state state, saved_state;
unsigned short vc_num; /* Console number */
unsigned int vc_cols; /* [#] Console size */
unsigned int vc_rows;
@ -73,8 +112,6 @@ struct vc_data {
/* attributes for all characters on screen */
unsigned char vc_attr; /* Current attributes */
unsigned char vc_def_color; /* Default colors */
unsigned char vc_color; /* Foreground & background */
unsigned char vc_s_color; /* Saved foreground & background */
unsigned char vc_ulcolor; /* Color for underline mode */
unsigned char vc_itcolor;
unsigned char vc_halfcolor; /* Color for half intensity mode */
@ -82,8 +119,6 @@ struct vc_data {
unsigned int vc_cursor_type;
unsigned short vc_complement_mask; /* [#] Xor mask for mouse pointer */
unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */
unsigned int vc_x, vc_y; /* Cursor position */
unsigned int vc_saved_x, vc_saved_y;
unsigned long vc_pos; /* Cursor address */
/* fonts */
unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
@ -98,8 +133,6 @@ struct vc_data {
int vt_newvt;
wait_queue_head_t paste_wait;
/* mode flags */
unsigned int vc_charset : 1; /* Character set G0 / G1 */
unsigned int vc_s_charset : 1; /* Saved character set */
unsigned int vc_disp_ctrl : 1; /* Display chars < 32? */
unsigned int vc_toggle_meta : 1; /* Toggle high bit? */
unsigned int vc_decscnm : 1; /* Screen Mode */
@ -107,17 +140,6 @@ struct vc_data {
unsigned int vc_decawm : 1; /* Autowrap Mode */
unsigned int vc_deccm : 1; /* Cursor Visible */
unsigned int vc_decim : 1; /* Insert Mode */
/* attribute flags */
unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
unsigned int vc_italic:1;
unsigned int vc_underline : 1;
unsigned int vc_blink : 1;
unsigned int vc_reverse : 1;
unsigned int vc_s_intensity : 2; /* saved rendition */
unsigned int vc_s_italic:1;
unsigned int vc_s_underline : 1;
unsigned int vc_s_blink : 1;
unsigned int vc_s_reverse : 1;
/* misc */
unsigned int vc_priv : 3;
unsigned int vc_need_wrap : 1;
@ -126,13 +148,9 @@ struct vc_data {
unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */
unsigned char vc_utf_count;
int vc_utf_char;
unsigned int vc_tab_stop[8]; /* Tab stops. 256 columns. */
DECLARE_BITMAP(vc_tab_stop, VC_TABSTOPS_COUNT); /* Tab stops. 256 columns. */
unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */
unsigned short * vc_translate;
unsigned char vc_G0_charset;
unsigned char vc_G1_charset;
unsigned char vc_saved_G0;
unsigned char vc_saved_G1;
unsigned int vc_resize_user; /* resize request from user */
unsigned int vc_bell_pitch; /* Console bell pitch */
unsigned int vc_bell_duration; /* Console bell duration */
@ -149,24 +167,29 @@ struct vc {
struct work_struct SAK_work;
/* might add scrmem, kbd at some time,
to have everything in one place - the disadvantage
would be that vc_cons etc can no longer be static */
to have everything in one place */
};
extern struct vc vc_cons [MAX_NR_CONSOLES];
extern void vc_SAK(struct work_struct *work);
#define CUR_DEF 0
#define CUR_NONE 1
#define CUR_UNDERLINE 2
#define CUR_LOWER_THIRD 3
#define CUR_LOWER_HALF 4
#define CUR_TWO_THIRDS 5
#define CUR_BLOCK 6
#define CUR_HWMASK 0x0f
#define CUR_SWMASK 0xfff0
#define CUR_DEFAULT CUR_UNDERLINE
#define CUR_MAKE(size, change, set) ((size) | ((change) << 8) | \
((set) << 16))
#define CUR_SIZE(c) ((c) & 0x00000f)
# define CUR_DEF 0
# define CUR_NONE 1
# define CUR_UNDERLINE 2
# define CUR_LOWER_THIRD 3
# define CUR_LOWER_HALF 4
# define CUR_TWO_THIRDS 5
# define CUR_BLOCK 6
#define CUR_SW 0x000010
#define CUR_ALWAYS_BG 0x000020
#define CUR_INVERT_FG_BG 0x000040
#define CUR_FG 0x000700
#define CUR_BG 0x007000
#define CUR_CHANGE(c) ((c) & 0x00ff00)
#define CUR_SET(c) (((c) & 0xff0000) >> 8)
bool con_is_visible(const struct vc_data *vc);

View File

@ -155,6 +155,8 @@ extern int early_serial_setup(struct uart_port *port);
extern int early_serial8250_setup(struct earlycon_device *device,
const char *options);
extern void serial8250_update_uartclk(struct uart_port *port,
unsigned int uartclk);
extern void serial8250_do_set_termios(struct uart_port *port,
struct ktermios *termios, struct ktermios *old);
extern void serial8250_do_set_ldisc(struct uart_port *port,

View File

@ -10,7 +10,6 @@
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/console.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/circ_buf.h>
#include <linux/spinlock.h>
@ -30,6 +29,7 @@
struct uart_port;
struct serial_struct;
struct device;
struct gpio_desc;
/*
* This structure describes all the operations that can be done on the

View File

@ -74,8 +74,6 @@ int con_set_default_unimap(struct vc_data *vc);
void con_free_unimap(struct vc_data *vc);
int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
#define vc_translate(vc, c) ((vc)->vc_translate[(c) | \
((vc)->vc_toggle_meta ? 0x80 : 0)])
#else
static inline int con_set_trans_old(unsigned char __user *table)
{
@ -124,7 +122,6 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
return 0;
}
#define vc_translate(vc, c) (c)
#endif
/* vt.c */

View File

@ -26,20 +26,6 @@
/*
* The type definitions. These are from Ted Ts'o's serial.h
*/
#define PORT_UNKNOWN 0
#define PORT_8250 1
#define PORT_16450 2
#define PORT_16550 3
#define PORT_16550A 4
#define PORT_CIRRUS 5
#define PORT_16650 6
#define PORT_16650V2 7
#define PORT_16750 8
#define PORT_STARTECH 9
#define PORT_16C950 10
#define PORT_16654 11
#define PORT_16850 12
#define PORT_RSA 13
#define PORT_NS16550A 14
#define PORT_XSCALE 15
#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */