aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-20 14:24:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-20 14:24:39 -0400
commit843ec558f91b8e8fdb6efc908f2c0506407cc750 (patch)
tree1866dccbc298390fc8686875942324075fd83f9d /arch/alpha
parent71e7ff2578c3bc67fd893a9ba7f69fd563f271de (diff)
parentfb8ebec00b04f921ea1614a7303f1a8e5e9e47c5 (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.c78
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
32struct srmcons_private { 32struct 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
38typedef union _srmcons_result { 37typedef union _srmcons_result {
39 struct { 38 struct {
@@ -68,22 +67,21 @@ static void
68srmcons_receive_chars(unsigned long data) 67srmcons_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
158static int 156static int
159srmcons_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
185static int
186srmcons_open(struct tty_struct *tty, struct file *filp) 157srmcons_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
214srmcons_close(struct tty_struct *tty, struct file *filp) 178srmcons_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 = {
240static int __init 205static int __init
241srmcons_init(void) 206srmcons_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;