diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 14:24:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 14:24:39 -0400 |
commit | 843ec558f91b8e8fdb6efc908f2c0506407cc750 (patch) | |
tree | 1866dccbc298390fc8686875942324075fd83f9d /arch/alpha | |
parent | 71e7ff2578c3bc67fd893a9ba7f69fd563f271de (diff) | |
parent | fb8ebec00b04f921ea1614a7303f1a8e5e9e47c5 (diff) |
Merge tag 'tty-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY/serial patches from Greg KH:
"tty and serial merge for 3.4-rc1
Here's the big serial and tty merge for the 3.4-rc1 tree.
There's loads of fixes and reworks in here from Jiri for the tty
layer, and a number of patches from Alan to help try to wrestle the vt
layer into a sane model.
Other than that, lots of driver updates and fixes, and other minor
stuff, all detailed in the shortlog."
* tag 'tty-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (132 commits)
serial: pxa: add clk_prepare/clk_unprepare calls
TTY: Wrong unicode value copied in con_set_unimap()
serial: PL011: clear pending interrupts
serial: bfin-uart: Don't access tty circular buffer in TX DMA interrupt after it is reset.
vt: NULL dereference in vt_do_kdsk_ioctl()
tty: serial: vt8500: fix annotations for probe/remove
serial: remove back and forth conversions in serial_out_sync
serial: use serial_port_in/out vs serial_in/out in 8250
serial: introduce generic port in/out helpers
serial: reduce number of indirections in 8250 code
serial: delete useless void casts in 8250.c
serial: make 8250's serial_in shareable to other drivers.
serial: delete last unused traces of pausing I/O in 8250
pch_uart: Add module parameter descriptions
pch_uart: Use existing default_baud in setup_console
pch_uart: Add user_uartclk parameter
pch_uart: Add Fish River Island II uart clock quirks
pch_uart: Use uartclk instead of base_baud
mpc5200b/uart: select more tolerant uart prescaler on low baudrates
tty: moxa: fix bit test in moxa_start()
...
Diffstat (limited to 'arch/alpha')
-rw-r--r-- | arch/alpha/kernel/srmcons.c | 78 |
1 files changed, 23 insertions, 55 deletions
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 783f4e50c111..3ea809430eda 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c | |||
@@ -30,10 +30,9 @@ static int srm_is_registered_console = 0; | |||
30 | #define MAX_SRM_CONSOLE_DEVICES 1 /* only support 1 console device */ | 30 | #define MAX_SRM_CONSOLE_DEVICES 1 /* only support 1 console device */ |
31 | 31 | ||
32 | struct srmcons_private { | 32 | struct srmcons_private { |
33 | struct tty_struct *tty; | 33 | struct tty_port port; |
34 | struct timer_list timer; | 34 | struct timer_list timer; |
35 | spinlock_t lock; | 35 | } srmcons_singleton; |
36 | }; | ||
37 | 36 | ||
38 | typedef union _srmcons_result { | 37 | typedef union _srmcons_result { |
39 | struct { | 38 | struct { |
@@ -68,22 +67,21 @@ static void | |||
68 | srmcons_receive_chars(unsigned long data) | 67 | srmcons_receive_chars(unsigned long data) |
69 | { | 68 | { |
70 | struct srmcons_private *srmconsp = (struct srmcons_private *)data; | 69 | struct srmcons_private *srmconsp = (struct srmcons_private *)data; |
70 | struct tty_port *port = &srmconsp->port; | ||
71 | unsigned long flags; | 71 | unsigned long flags; |
72 | int incr = 10; | 72 | int incr = 10; |
73 | 73 | ||
74 | local_irq_save(flags); | 74 | local_irq_save(flags); |
75 | if (spin_trylock(&srmcons_callback_lock)) { | 75 | if (spin_trylock(&srmcons_callback_lock)) { |
76 | if (!srmcons_do_receive_chars(srmconsp->tty)) | 76 | if (!srmcons_do_receive_chars(port->tty)) |
77 | incr = 100; | 77 | incr = 100; |
78 | spin_unlock(&srmcons_callback_lock); | 78 | spin_unlock(&srmcons_callback_lock); |
79 | } | 79 | } |
80 | 80 | ||
81 | spin_lock(&srmconsp->lock); | 81 | spin_lock(&port->lock); |
82 | if (srmconsp->tty) { | 82 | if (port->tty) |
83 | srmconsp->timer.expires = jiffies + incr; | 83 | mod_timer(&srmconsp->timer, jiffies + incr); |
84 | add_timer(&srmconsp->timer); | 84 | spin_unlock(&port->lock); |
85 | } | ||
86 | spin_unlock(&srmconsp->lock); | ||
87 | 85 | ||
88 | local_irq_restore(flags); | 86 | local_irq_restore(flags); |
89 | } | 87 | } |
@@ -156,56 +154,22 @@ srmcons_chars_in_buffer(struct tty_struct *tty) | |||
156 | } | 154 | } |
157 | 155 | ||
158 | static int | 156 | static int |
159 | srmcons_get_private_struct(struct srmcons_private **ps) | ||
160 | { | ||
161 | static struct srmcons_private *srmconsp = NULL; | ||
162 | static DEFINE_SPINLOCK(srmconsp_lock); | ||
163 | unsigned long flags; | ||
164 | int retval = 0; | ||
165 | |||
166 | if (srmconsp == NULL) { | ||
167 | srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); | ||
168 | spin_lock_irqsave(&srmconsp_lock, flags); | ||
169 | |||
170 | if (srmconsp == NULL) | ||
171 | retval = -ENOMEM; | ||
172 | else { | ||
173 | srmconsp->tty = NULL; | ||
174 | spin_lock_init(&srmconsp->lock); | ||
175 | init_timer(&srmconsp->timer); | ||
176 | } | ||
177 | |||
178 | spin_unlock_irqrestore(&srmconsp_lock, flags); | ||
179 | } | ||
180 | |||
181 | *ps = srmconsp; | ||
182 | return retval; | ||
183 | } | ||
184 | |||
185 | static int | ||
186 | srmcons_open(struct tty_struct *tty, struct file *filp) | 157 | srmcons_open(struct tty_struct *tty, struct file *filp) |
187 | { | 158 | { |
188 | struct srmcons_private *srmconsp; | 159 | struct srmcons_private *srmconsp = &srmcons_singleton; |
160 | struct tty_port *port = &srmconsp->port; | ||
189 | unsigned long flags; | 161 | unsigned long flags; |
190 | int retval; | ||
191 | |||
192 | retval = srmcons_get_private_struct(&srmconsp); | ||
193 | if (retval) | ||
194 | return retval; | ||
195 | 162 | ||
196 | spin_lock_irqsave(&srmconsp->lock, flags); | 163 | spin_lock_irqsave(&port->lock, flags); |
197 | 164 | ||
198 | if (!srmconsp->tty) { | 165 | if (!port->tty) { |
199 | tty->driver_data = srmconsp; | 166 | tty->driver_data = srmconsp; |
200 | 167 | tty->port = port; | |
201 | srmconsp->tty = tty; | 168 | port->tty = tty; /* XXX proper refcounting */ |
202 | srmconsp->timer.function = srmcons_receive_chars; | 169 | mod_timer(&srmconsp->timer, jiffies + 10); |
203 | srmconsp->timer.data = (unsigned long)srmconsp; | ||
204 | srmconsp->timer.expires = jiffies + 10; | ||
205 | add_timer(&srmconsp->timer); | ||
206 | } | 170 | } |
207 | 171 | ||
208 | spin_unlock_irqrestore(&srmconsp->lock, flags); | 172 | spin_unlock_irqrestore(&port->lock, flags); |
209 | 173 | ||
210 | return 0; | 174 | return 0; |
211 | } | 175 | } |
@@ -214,16 +178,17 @@ static void | |||
214 | srmcons_close(struct tty_struct *tty, struct file *filp) | 178 | srmcons_close(struct tty_struct *tty, struct file *filp) |
215 | { | 179 | { |
216 | struct srmcons_private *srmconsp = tty->driver_data; | 180 | struct srmcons_private *srmconsp = tty->driver_data; |
181 | struct tty_port *port = &srmconsp->port; | ||
217 | unsigned long flags; | 182 | unsigned long flags; |
218 | 183 | ||
219 | spin_lock_irqsave(&srmconsp->lock, flags); | 184 | spin_lock_irqsave(&port->lock, flags); |
220 | 185 | ||
221 | if (tty->count == 1) { | 186 | if (tty->count == 1) { |
222 | srmconsp->tty = NULL; | 187 | port->tty = NULL; |
223 | del_timer(&srmconsp->timer); | 188 | del_timer(&srmconsp->timer); |
224 | } | 189 | } |
225 | 190 | ||
226 | spin_unlock_irqrestore(&srmconsp->lock, flags); | 191 | spin_unlock_irqrestore(&port->lock, flags); |
227 | } | 192 | } |
228 | 193 | ||
229 | 194 | ||
@@ -240,6 +205,9 @@ static const struct tty_operations srmcons_ops = { | |||
240 | static int __init | 205 | static int __init |
241 | srmcons_init(void) | 206 | srmcons_init(void) |
242 | { | 207 | { |
208 | tty_port_init(&srmcons_singleton.port); | ||
209 | setup_timer(&srmcons_singleton.timer, srmcons_receive_chars, | ||
210 | (unsigned long)&srmcons_singleton); | ||
243 | if (srm_is_registered_console) { | 211 | if (srm_is_registered_console) { |
244 | struct tty_driver *driver; | 212 | struct tty_driver *driver; |
245 | int err; | 213 | int err; |