diff options
Diffstat (limited to 'drivers/serial/altera_uart.c')
-rw-r--r-- | drivers/serial/altera_uart.c | 44 |
1 files changed, 13 insertions, 31 deletions
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c index bcee156d2f2e..0f1189605d21 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/serial/altera_uart.c | |||
@@ -89,15 +89,12 @@ static unsigned int altera_uart_tx_empty(struct uart_port *port) | |||
89 | static unsigned int altera_uart_get_mctrl(struct uart_port *port) | 89 | static unsigned int altera_uart_get_mctrl(struct uart_port *port) |
90 | { | 90 | { |
91 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 91 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
92 | unsigned long flags; | ||
93 | unsigned int sigs; | 92 | unsigned int sigs; |
94 | 93 | ||
95 | spin_lock_irqsave(&port->lock, flags); | ||
96 | sigs = | 94 | sigs = |
97 | (readl(port->membase + ALTERA_UART_STATUS_REG) & | 95 | (readl(port->membase + ALTERA_UART_STATUS_REG) & |
98 | ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; | 96 | ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; |
99 | sigs |= (pp->sigs & TIOCM_RTS); | 97 | sigs |= (pp->sigs & TIOCM_RTS); |
100 | spin_unlock_irqrestore(&port->lock, flags); | ||
101 | 98 | ||
102 | return sigs; | 99 | return sigs; |
103 | } | 100 | } |
@@ -105,49 +102,37 @@ static unsigned int altera_uart_get_mctrl(struct uart_port *port) | |||
105 | static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) | 102 | static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) |
106 | { | 103 | { |
107 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 104 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
108 | unsigned long flags; | ||
109 | 105 | ||
110 | spin_lock_irqsave(&port->lock, flags); | ||
111 | pp->sigs = sigs; | 106 | pp->sigs = sigs; |
112 | if (sigs & TIOCM_RTS) | 107 | if (sigs & TIOCM_RTS) |
113 | pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; | 108 | pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; |
114 | else | 109 | else |
115 | pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; | 110 | pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; |
116 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 111 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); |
117 | spin_unlock_irqrestore(&port->lock, flags); | ||
118 | } | 112 | } |
119 | 113 | ||
120 | static void altera_uart_start_tx(struct uart_port *port) | 114 | static void altera_uart_start_tx(struct uart_port *port) |
121 | { | 115 | { |
122 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 116 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
123 | unsigned long flags; | ||
124 | 117 | ||
125 | spin_lock_irqsave(&port->lock, flags); | ||
126 | pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; | 118 | pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; |
127 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 119 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); |
128 | spin_unlock_irqrestore(&port->lock, flags); | ||
129 | } | 120 | } |
130 | 121 | ||
131 | static void altera_uart_stop_tx(struct uart_port *port) | 122 | static void altera_uart_stop_tx(struct uart_port *port) |
132 | { | 123 | { |
133 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 124 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
134 | unsigned long flags; | ||
135 | 125 | ||
136 | spin_lock_irqsave(&port->lock, flags); | ||
137 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | 126 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; |
138 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 127 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); |
139 | spin_unlock_irqrestore(&port->lock, flags); | ||
140 | } | 128 | } |
141 | 129 | ||
142 | static void altera_uart_stop_rx(struct uart_port *port) | 130 | static void altera_uart_stop_rx(struct uart_port *port) |
143 | { | 131 | { |
144 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 132 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
145 | unsigned long flags; | ||
146 | 133 | ||
147 | spin_lock_irqsave(&port->lock, flags); | ||
148 | pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; | 134 | pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; |
149 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 135 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); |
150 | spin_unlock_irqrestore(&port->lock, flags); | ||
151 | } | 136 | } |
152 | 137 | ||
153 | static void altera_uart_break_ctl(struct uart_port *port, int break_state) | 138 | static void altera_uart_break_ctl(struct uart_port *port, int break_state) |
@@ -272,10 +257,14 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data) | |||
272 | unsigned int isr; | 257 | unsigned int isr; |
273 | 258 | ||
274 | isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; | 259 | isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; |
260 | |||
261 | spin_lock(&port->lock); | ||
275 | if (isr & ALTERA_UART_STATUS_RRDY_MSK) | 262 | if (isr & ALTERA_UART_STATUS_RRDY_MSK) |
276 | altera_uart_rx_chars(pp); | 263 | altera_uart_rx_chars(pp); |
277 | if (isr & ALTERA_UART_STATUS_TRDY_MSK) | 264 | if (isr & ALTERA_UART_STATUS_TRDY_MSK) |
278 | altera_uart_tx_chars(pp); | 265 | altera_uart_tx_chars(pp); |
266 | spin_unlock(&port->lock); | ||
267 | |||
279 | return IRQ_RETVAL(isr); | 268 | return IRQ_RETVAL(isr); |
280 | } | 269 | } |
281 | 270 | ||
@@ -402,31 +391,24 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) | |||
402 | return 0; | 391 | return 0; |
403 | } | 392 | } |
404 | 393 | ||
405 | static void altera_uart_console_putc(struct console *co, const char c) | 394 | static void altera_uart_console_putc(struct uart_port *port, const char c) |
406 | { | 395 | { |
407 | struct uart_port *port = &(altera_uart_ports + co->index)->port; | 396 | while (!(readl(port->membase + ALTERA_UART_STATUS_REG) & |
408 | int i; | 397 | ALTERA_UART_STATUS_TRDY_MSK)) |
398 | cpu_relax(); | ||
409 | 399 | ||
410 | for (i = 0; i < 0x10000; i++) { | ||
411 | if (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
412 | ALTERA_UART_STATUS_TRDY_MSK) | ||
413 | break; | ||
414 | } | ||
415 | writel(c, port->membase + ALTERA_UART_TXDATA_REG); | 400 | writel(c, port->membase + ALTERA_UART_TXDATA_REG); |
416 | for (i = 0; i < 0x10000; i++) { | ||
417 | if (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
418 | ALTERA_UART_STATUS_TRDY_MSK) | ||
419 | break; | ||
420 | } | ||
421 | } | 401 | } |
422 | 402 | ||
423 | static void altera_uart_console_write(struct console *co, const char *s, | 403 | static void altera_uart_console_write(struct console *co, const char *s, |
424 | unsigned int count) | 404 | unsigned int count) |
425 | { | 405 | { |
406 | struct uart_port *port = &(altera_uart_ports + co->index)->port; | ||
407 | |||
426 | for (; count; count--, s++) { | 408 | for (; count; count--, s++) { |
427 | altera_uart_console_putc(co, *s); | 409 | altera_uart_console_putc(port, *s); |
428 | if (*s == '\n') | 410 | if (*s == '\n') |
429 | altera_uart_console_putc(co, '\r'); | 411 | altera_uart_console_putc(port, '\r'); |
430 | } | 412 | } |
431 | } | 413 | } |
432 | 414 | ||
@@ -516,7 +498,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
516 | return 0; | 498 | return 0; |
517 | } | 499 | } |
518 | 500 | ||
519 | static int altera_uart_remove(struct platform_device *pdev) | 501 | static int __devexit altera_uart_remove(struct platform_device *pdev) |
520 | { | 502 | { |
521 | struct uart_port *port; | 503 | struct uart_port *port; |
522 | int i; | 504 | int i; |