diff options
Diffstat (limited to 'drivers/serial/mcf.c')
| -rw-r--r-- | drivers/serial/mcf.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c index b5aaef965f24..3394b7cc1722 100644 --- a/drivers/serial/mcf.c +++ b/drivers/serial/mcf.c | |||
| @@ -70,16 +70,14 @@ static unsigned int mcf_tx_empty(struct uart_port *port) | |||
| 70 | static unsigned int mcf_get_mctrl(struct uart_port *port) | 70 | static unsigned int mcf_get_mctrl(struct uart_port *port) |
| 71 | { | 71 | { |
| 72 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 72 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 73 | unsigned long flags; | ||
| 74 | unsigned int sigs; | 73 | unsigned int sigs; |
| 75 | 74 | ||
| 76 | spin_lock_irqsave(&port->lock, flags); | ||
| 77 | sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? | 75 | sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? |
| 78 | 0 : TIOCM_CTS; | 76 | 0 : TIOCM_CTS; |
| 79 | sigs |= (pp->sigs & TIOCM_RTS); | 77 | sigs |= (pp->sigs & TIOCM_RTS); |
| 80 | sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); | 78 | sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); |
| 81 | sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); | 79 | sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); |
| 82 | spin_unlock_irqrestore(&port->lock, flags); | 80 | |
| 83 | return sigs; | 81 | return sigs; |
| 84 | } | 82 | } |
| 85 | 83 | ||
| @@ -88,16 +86,13 @@ static unsigned int mcf_get_mctrl(struct uart_port *port) | |||
| 88 | static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) | 86 | static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) |
| 89 | { | 87 | { |
| 90 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 88 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 91 | unsigned long flags; | ||
| 92 | 89 | ||
| 93 | spin_lock_irqsave(&port->lock, flags); | ||
| 94 | pp->sigs = sigs; | 90 | pp->sigs = sigs; |
| 95 | mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); | 91 | mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); |
| 96 | if (sigs & TIOCM_RTS) | 92 | if (sigs & TIOCM_RTS) |
| 97 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); | 93 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); |
| 98 | else | 94 | else |
| 99 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); | 95 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); |
| 100 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 101 | } | 96 | } |
| 102 | 97 | ||
| 103 | /****************************************************************************/ | 98 | /****************************************************************************/ |
| @@ -105,12 +100,9 @@ static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) | |||
| 105 | static void mcf_start_tx(struct uart_port *port) | 100 | static void mcf_start_tx(struct uart_port *port) |
| 106 | { | 101 | { |
| 107 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 102 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 108 | unsigned long flags; | ||
| 109 | 103 | ||
| 110 | spin_lock_irqsave(&port->lock, flags); | ||
| 111 | pp->imr |= MCFUART_UIR_TXREADY; | 104 | pp->imr |= MCFUART_UIR_TXREADY; |
| 112 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 105 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
| 113 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 114 | } | 106 | } |
| 115 | 107 | ||
| 116 | /****************************************************************************/ | 108 | /****************************************************************************/ |
| @@ -118,12 +110,9 @@ static void mcf_start_tx(struct uart_port *port) | |||
| 118 | static void mcf_stop_tx(struct uart_port *port) | 110 | static void mcf_stop_tx(struct uart_port *port) |
| 119 | { | 111 | { |
| 120 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 112 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 121 | unsigned long flags; | ||
| 122 | 113 | ||
| 123 | spin_lock_irqsave(&port->lock, flags); | ||
| 124 | pp->imr &= ~MCFUART_UIR_TXREADY; | 114 | pp->imr &= ~MCFUART_UIR_TXREADY; |
| 125 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 115 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
| 126 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 127 | } | 116 | } |
| 128 | 117 | ||
| 129 | /****************************************************************************/ | 118 | /****************************************************************************/ |
| @@ -131,12 +120,9 @@ static void mcf_stop_tx(struct uart_port *port) | |||
| 131 | static void mcf_stop_rx(struct uart_port *port) | 120 | static void mcf_stop_rx(struct uart_port *port) |
| 132 | { | 121 | { |
| 133 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 122 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 134 | unsigned long flags; | ||
| 135 | 123 | ||
| 136 | spin_lock_irqsave(&port->lock, flags); | ||
| 137 | pp->imr &= ~MCFUART_UIR_RXREADY; | 124 | pp->imr &= ~MCFUART_UIR_RXREADY; |
| 138 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 125 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
| 139 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 140 | } | 126 | } |
| 141 | 127 | ||
| 142 | /****************************************************************************/ | 128 | /****************************************************************************/ |
| @@ -366,13 +352,22 @@ static irqreturn_t mcf_interrupt(int irq, void *data) | |||
| 366 | struct uart_port *port = data; | 352 | struct uart_port *port = data; |
| 367 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 353 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 368 | unsigned int isr; | 354 | unsigned int isr; |
| 355 | irqreturn_t ret = IRQ_NONE; | ||
| 369 | 356 | ||
| 370 | isr = readb(port->membase + MCFUART_UISR) & pp->imr; | 357 | isr = readb(port->membase + MCFUART_UISR) & pp->imr; |
| 371 | if (isr & MCFUART_UIR_RXREADY) | 358 | |
| 359 | spin_lock(&port->lock); | ||
| 360 | if (isr & MCFUART_UIR_RXREADY) { | ||
| 372 | mcf_rx_chars(pp); | 361 | mcf_rx_chars(pp); |
| 373 | if (isr & MCFUART_UIR_TXREADY) | 362 | ret = IRQ_HANDLED; |
| 363 | } | ||
| 364 | if (isr & MCFUART_UIR_TXREADY) { | ||
| 374 | mcf_tx_chars(pp); | 365 | mcf_tx_chars(pp); |
| 375 | return IRQ_HANDLED; | 366 | ret = IRQ_HANDLED; |
| 367 | } | ||
| 368 | spin_unlock(&port->lock); | ||
| 369 | |||
| 370 | return ret; | ||
| 376 | } | 371 | } |
| 377 | 372 | ||
| 378 | /****************************************************************************/ | 373 | /****************************************************************************/ |
