aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 16:41:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 16:41:04 -0500
commit21eaab6d19ed43e82ed39c8deb7f192134fb4a0e (patch)
treed995205afdcb7f47462bcd28067dc0c4ab0b7b02 /arch/um
parent74e1a2a39355b2d3ae8c60c78d8add162c6d7183 (diff)
parent9e17df37d710f8998e9cb10a548304fe33d4a5c2 (diff)
Merge tag 'tty-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial patches from Greg Kroah-Hartman: "Here's the big tty/serial driver patches for 3.9-rc1. More tty port rework and fixes from Jiri here, as well as lots of individual serial driver updates and fixes. All of these have been in the linux-next tree for a while." * tag 'tty-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (140 commits) tty: mxser: improve error handling in mxser_probe() and mxser_module_init() serial: imx: fix uninitialized variable warning serial: tegra: assume CONFIG_OF TTY: do not update atime/mtime on read/write lguest: select CONFIG_TTY to build properly. ARM defconfigs: add missing inclusions of linux/platform_device.h fb/exynos: include platform_device.h ARM: sa1100/assabet: include platform_device.h directly serial: imx: Fix recursive locking bug pps: Fix build breakage from decoupling pps from tty tty: Remove ancient hardpps() pps: Additional cleanups in uart_handle_dcd_change pps: Move timestamp read into PPS code proper pps: Don't crash the machine when exiting will do pps: Fix a use-after free bug when unregistering a source. pps: Use pps_lookup_dev to reduce ldisc coupling pps: Add pps_lookup_dev() function tty: serial: uartlite: Support uartlite on big and little endian systems tty: serial: uartlite: Fix sparse and checkpatch warnings serial/arc-uart: Miscll DT related updates (Grant's review comments) ... Fix up trivial conflicts, mostly just due to the TTY config option clashing with the EXPERIMENTAL removal.
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig.common1
-rw-r--r--arch/um/drivers/chan.h3
-rw-r--r--arch/um/drivers/chan_kern.c25
-rw-r--r--arch/um/drivers/line.c7
4 files changed, 15 insertions, 21 deletions
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 648121b037d5..bceee6623b00 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -12,6 +12,7 @@ config UML
12 select GENERIC_CPU_DEVICES 12 select GENERIC_CPU_DEVICES
13 select GENERIC_IO 13 select GENERIC_IO
14 select GENERIC_CLOCKEVENTS 14 select GENERIC_CLOCKEVENTS
15 select TTY # Needed for line.c
15 16
16config MMU 17config MMU
17 bool 18 bool
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h
index 02b5a76e98d9..78f1b8999964 100644
--- a/arch/um/drivers/chan.h
+++ b/arch/um/drivers/chan.h
@@ -27,8 +27,7 @@ struct chan {
27 void *data; 27 void *data;
28}; 28};
29 29
30extern void chan_interrupt(struct line *line, 30extern void chan_interrupt(struct line *line, int irq);
31 struct tty_struct *tty, int irq);
32extern int parse_chan_pair(char *str, struct line *line, int device, 31extern int parse_chan_pair(char *str, struct line *line, int device,
33 const struct chan_opts *opts, char **error_out); 32 const struct chan_opts *opts, char **error_out);
34extern int write_chan(struct chan *chan, const char *buf, int len, 33extern int write_chan(struct chan *chan, const char *buf, int len,
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index e9a0abc6a32f..15c553c239a1 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -81,12 +81,6 @@ static const struct chan_ops not_configged_ops = {
81}; 81};
82#endif /* CONFIG_NOCONFIG_CHAN */ 82#endif /* CONFIG_NOCONFIG_CHAN */
83 83
84static void tty_receive_char(struct tty_struct *tty, char ch)
85{
86 if (tty)
87 tty_insert_flip_char(tty, ch, TTY_NORMAL);
88}
89
90static int open_one_chan(struct chan *chan) 84static int open_one_chan(struct chan *chan)
91{ 85{
92 int fd, err; 86 int fd, err;
@@ -137,11 +131,9 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
137static void line_timer_cb(struct work_struct *work) 131static void line_timer_cb(struct work_struct *work)
138{ 132{
139 struct line *line = container_of(work, struct line, task.work); 133 struct line *line = container_of(work, struct line, task.work);
140 struct tty_struct *tty = tty_port_tty_get(&line->port);
141 134
142 if (!line->throttled) 135 if (!line->throttled)
143 chan_interrupt(line, tty, line->driver->read_irq); 136 chan_interrupt(line, line->driver->read_irq);
144 tty_kref_put(tty);
145} 137}
146 138
147int enable_chan(struct line *line) 139int enable_chan(struct line *line)
@@ -552,8 +544,9 @@ int parse_chan_pair(char *str, struct line *line, int device,
552 return 0; 544 return 0;
553} 545}
554 546
555void chan_interrupt(struct line *line, struct tty_struct *tty, int irq) 547void chan_interrupt(struct line *line, int irq)
556{ 548{
549 struct tty_port *port = &line->port;
557 struct chan *chan = line->chan_in; 550 struct chan *chan = line->chan_in;
558 int err; 551 int err;
559 char c; 552 char c;
@@ -562,21 +555,24 @@ void chan_interrupt(struct line *line, struct tty_struct *tty, int irq)
562 goto out; 555 goto out;
563 556
564 do { 557 do {
565 if (tty && !tty_buffer_request_room(tty, 1)) { 558 if (!tty_buffer_request_room(port, 1)) {
566 schedule_delayed_work(&line->task, 1); 559 schedule_delayed_work(&line->task, 1);
567 goto out; 560 goto out;
568 } 561 }
569 err = chan->ops->read(chan->fd, &c, chan->data); 562 err = chan->ops->read(chan->fd, &c, chan->data);
570 if (err > 0) 563 if (err > 0)
571 tty_receive_char(tty, c); 564 tty_insert_flip_char(port, c, TTY_NORMAL);
572 } while (err > 0); 565 } while (err > 0);
573 566
574 if (err == 0) 567 if (err == 0)
575 reactivate_fd(chan->fd, irq); 568 reactivate_fd(chan->fd, irq);
576 if (err == -EIO) { 569 if (err == -EIO) {
577 if (chan->primary) { 570 if (chan->primary) {
578 if (tty != NULL) 571 struct tty_struct *tty = tty_port_tty_get(&line->port);
572 if (tty != NULL) {
579 tty_hangup(tty); 573 tty_hangup(tty);
574 tty_kref_put(tty);
575 }
580 if (line->chan_out != chan) 576 if (line->chan_out != chan)
581 close_one_chan(line->chan_out, 1); 577 close_one_chan(line->chan_out, 1);
582 } 578 }
@@ -585,6 +581,5 @@ void chan_interrupt(struct line *line, struct tty_struct *tty, int irq)
585 return; 581 return;
586 } 582 }
587 out: 583 out:
588 if (tty) 584 tty_flip_buffer_push(port);
589 tty_flip_buffer_push(tty);
590} 585}
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 9ffc28bd4b7a..f1b38571f94e 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -19,11 +19,10 @@ static irqreturn_t line_interrupt(int irq, void *data)
19{ 19{
20 struct chan *chan = data; 20 struct chan *chan = data;
21 struct line *line = chan->line; 21 struct line *line = chan->line;
22 struct tty_struct *tty = tty_port_tty_get(&line->port);
23 22
24 if (line) 23 if (line)
25 chan_interrupt(line, tty, irq); 24 chan_interrupt(line, irq);
26 tty_kref_put(tty); 25
27 return IRQ_HANDLED; 26 return IRQ_HANDLED;
28} 27}
29 28
@@ -234,7 +233,7 @@ void line_unthrottle(struct tty_struct *tty)
234 struct line *line = tty->driver_data; 233 struct line *line = tty->driver_data;
235 234
236 line->throttled = 0; 235 line->throttled = 0;
237 chan_interrupt(line, tty, line->driver->read_irq); 236 chan_interrupt(line, line->driver->read_irq);
238 237
239 /* 238 /*
240 * Maybe there is enough stuff pending that calling the interrupt 239 * Maybe there is enough stuff pending that calling the interrupt