diff options
-rw-r--r-- | drivers/serial/altera_uart.c | 58 | ||||
-rw-r--r-- | include/linux/altera_uart.h | 1 |
2 files changed, 38 insertions, 21 deletions
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c index 1dfeffae5231..f1985aaf2cbc 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/serial/altera_uart.c | |||
@@ -82,9 +82,23 @@ struct altera_uart { | |||
82 | unsigned short imr; /* Local IMR mirror */ | 82 | unsigned short imr; /* Local IMR mirror */ |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static u32 altera_uart_readl(struct uart_port *port, int reg) | ||
86 | { | ||
87 | struct altera_uart_platform_uart *platp = port->private_data; | ||
88 | |||
89 | return readl(port->membase + (reg << platp->bus_shift)); | ||
90 | } | ||
91 | |||
92 | static void altera_uart_writel(struct uart_port *port, u32 dat, int reg) | ||
93 | { | ||
94 | struct altera_uart_platform_uart *platp = port->private_data; | ||
95 | |||
96 | writel(dat, port->membase + (reg << platp->bus_shift)); | ||
97 | } | ||
98 | |||
85 | static unsigned int altera_uart_tx_empty(struct uart_port *port) | 99 | static unsigned int altera_uart_tx_empty(struct uart_port *port) |
86 | { | 100 | { |
87 | return (readl(port->membase + ALTERA_UART_STATUS_REG) & | 101 | return (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & |
88 | ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0; | 102 | ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0; |
89 | } | 103 | } |
90 | 104 | ||
@@ -93,8 +107,7 @@ static unsigned int altera_uart_get_mctrl(struct uart_port *port) | |||
93 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 107 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
94 | unsigned int sigs; | 108 | unsigned int sigs; |
95 | 109 | ||
96 | sigs = | 110 | sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & |
97 | (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
98 | ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; | 111 | ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; |
99 | sigs |= (pp->sigs & TIOCM_RTS); | 112 | sigs |= (pp->sigs & TIOCM_RTS); |
100 | 113 | ||
@@ -110,7 +123,7 @@ static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) | |||
110 | pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; | 123 | pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; |
111 | else | 124 | else |
112 | pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; | 125 | pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; |
113 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 126 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); |
114 | } | 127 | } |
115 | 128 | ||
116 | static void altera_uart_start_tx(struct uart_port *port) | 129 | static void altera_uart_start_tx(struct uart_port *port) |
@@ -118,7 +131,7 @@ static void altera_uart_start_tx(struct uart_port *port) | |||
118 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 131 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
119 | 132 | ||
120 | pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; | 133 | pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; |
121 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 134 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); |
122 | } | 135 | } |
123 | 136 | ||
124 | static void altera_uart_stop_tx(struct uart_port *port) | 137 | static void altera_uart_stop_tx(struct uart_port *port) |
@@ -126,7 +139,7 @@ static void altera_uart_stop_tx(struct uart_port *port) | |||
126 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 139 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
127 | 140 | ||
128 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | 141 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; |
129 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 142 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); |
130 | } | 143 | } |
131 | 144 | ||
132 | static void altera_uart_stop_rx(struct uart_port *port) | 145 | static void altera_uart_stop_rx(struct uart_port *port) |
@@ -134,7 +147,7 @@ static void altera_uart_stop_rx(struct uart_port *port) | |||
134 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 147 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
135 | 148 | ||
136 | pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; | 149 | pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; |
137 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 150 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); |
138 | } | 151 | } |
139 | 152 | ||
140 | static void altera_uart_break_ctl(struct uart_port *port, int break_state) | 153 | static void altera_uart_break_ctl(struct uart_port *port, int break_state) |
@@ -147,7 +160,7 @@ static void altera_uart_break_ctl(struct uart_port *port, int break_state) | |||
147 | pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; | 160 | pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; |
148 | else | 161 | else |
149 | pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; | 162 | pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; |
150 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 163 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); |
151 | spin_unlock_irqrestore(&port->lock, flags); | 164 | spin_unlock_irqrestore(&port->lock, flags); |
152 | } | 165 | } |
153 | 166 | ||
@@ -171,7 +184,7 @@ static void altera_uart_set_termios(struct uart_port *port, | |||
171 | 184 | ||
172 | spin_lock_irqsave(&port->lock, flags); | 185 | spin_lock_irqsave(&port->lock, flags); |
173 | uart_update_timeout(port, termios->c_cflag, baud); | 186 | uart_update_timeout(port, termios->c_cflag, baud); |
174 | writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG); | 187 | altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG); |
175 | spin_unlock_irqrestore(&port->lock, flags); | 188 | spin_unlock_irqrestore(&port->lock, flags); |
176 | } | 189 | } |
177 | 190 | ||
@@ -181,14 +194,15 @@ static void altera_uart_rx_chars(struct altera_uart *pp) | |||
181 | unsigned char ch, flag; | 194 | unsigned char ch, flag; |
182 | unsigned short status; | 195 | unsigned short status; |
183 | 196 | ||
184 | while ((status = readl(port->membase + ALTERA_UART_STATUS_REG)) & | 197 | while ((status = altera_uart_readl(port, ALTERA_UART_STATUS_REG)) & |
185 | ALTERA_UART_STATUS_RRDY_MSK) { | 198 | ALTERA_UART_STATUS_RRDY_MSK) { |
186 | ch = readl(port->membase + ALTERA_UART_RXDATA_REG); | 199 | ch = altera_uart_readl(port, ALTERA_UART_RXDATA_REG); |
187 | flag = TTY_NORMAL; | 200 | flag = TTY_NORMAL; |
188 | port->icount.rx++; | 201 | port->icount.rx++; |
189 | 202 | ||
190 | if (status & ALTERA_UART_STATUS_E_MSK) { | 203 | if (status & ALTERA_UART_STATUS_E_MSK) { |
191 | writel(status, port->membase + ALTERA_UART_STATUS_REG); | 204 | altera_uart_writel(port, status, |
205 | ALTERA_UART_STATUS_REG); | ||
192 | 206 | ||
193 | if (status & ALTERA_UART_STATUS_BRK_MSK) { | 207 | if (status & ALTERA_UART_STATUS_BRK_MSK) { |
194 | port->icount.brk++; | 208 | port->icount.brk++; |
@@ -228,18 +242,18 @@ static void altera_uart_tx_chars(struct altera_uart *pp) | |||
228 | 242 | ||
229 | if (port->x_char) { | 243 | if (port->x_char) { |
230 | /* Send special char - probably flow control */ | 244 | /* Send special char - probably flow control */ |
231 | writel(port->x_char, port->membase + ALTERA_UART_TXDATA_REG); | 245 | altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG); |
232 | port->x_char = 0; | 246 | port->x_char = 0; |
233 | port->icount.tx++; | 247 | port->icount.tx++; |
234 | return; | 248 | return; |
235 | } | 249 | } |
236 | 250 | ||
237 | while (readl(port->membase + ALTERA_UART_STATUS_REG) & | 251 | while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & |
238 | ALTERA_UART_STATUS_TRDY_MSK) { | 252 | ALTERA_UART_STATUS_TRDY_MSK) { |
239 | if (xmit->head == xmit->tail) | 253 | if (xmit->head == xmit->tail) |
240 | break; | 254 | break; |
241 | writel(xmit->buf[xmit->tail], | 255 | altera_uart_writel(port, xmit->buf[xmit->tail], |
242 | port->membase + ALTERA_UART_TXDATA_REG); | 256 | ALTERA_UART_TXDATA_REG); |
243 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 257 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
244 | port->icount.tx++; | 258 | port->icount.tx++; |
245 | } | 259 | } |
@@ -249,7 +263,7 @@ static void altera_uart_tx_chars(struct altera_uart *pp) | |||
249 | 263 | ||
250 | if (xmit->head == xmit->tail) { | 264 | if (xmit->head == xmit->tail) { |
251 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | 265 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; |
252 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | 266 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); |
253 | } | 267 | } |
254 | } | 268 | } |
255 | 269 | ||
@@ -259,7 +273,7 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data) | |||
259 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | 273 | struct altera_uart *pp = container_of(port, struct altera_uart, port); |
260 | unsigned int isr; | 274 | unsigned int isr; |
261 | 275 | ||
262 | isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; | 276 | isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr; |
263 | 277 | ||
264 | spin_lock(&port->lock); | 278 | spin_lock(&port->lock); |
265 | if (isr & ALTERA_UART_STATUS_RRDY_MSK) | 279 | if (isr & ALTERA_UART_STATUS_RRDY_MSK) |
@@ -285,9 +299,9 @@ static void altera_uart_config_port(struct uart_port *port, int flags) | |||
285 | port->type = PORT_ALTERA_UART; | 299 | port->type = PORT_ALTERA_UART; |
286 | 300 | ||
287 | /* Clear mask, so no surprise interrupts. */ | 301 | /* Clear mask, so no surprise interrupts. */ |
288 | writel(0, port->membase + ALTERA_UART_CONTROL_REG); | 302 | altera_uart_writel(port, 0, ALTERA_UART_CONTROL_REG); |
289 | /* Clear status register */ | 303 | /* Clear status register */ |
290 | writel(0, port->membase + ALTERA_UART_STATUS_REG); | 304 | altera_uart_writel(port, 0, ALTERA_UART_STATUS_REG); |
291 | } | 305 | } |
292 | 306 | ||
293 | static int altera_uart_startup(struct uart_port *port) | 307 | static int altera_uart_startup(struct uart_port *port) |
@@ -407,6 +421,7 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) | |||
407 | port->uartclk = platp[i].uartclk; | 421 | port->uartclk = platp[i].uartclk; |
408 | port->flags = ASYNC_BOOT_AUTOCONF; | 422 | port->flags = ASYNC_BOOT_AUTOCONF; |
409 | port->ops = &altera_uart_ops; | 423 | port->ops = &altera_uart_ops; |
424 | port->private_data = platp; | ||
410 | } | 425 | } |
411 | 426 | ||
412 | return 0; | 427 | return 0; |
@@ -414,7 +429,7 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) | |||
414 | 429 | ||
415 | static void altera_uart_console_putc(struct uart_port *port, const char c) | 430 | static void altera_uart_console_putc(struct uart_port *port, const char c) |
416 | { | 431 | { |
417 | while (!(readl(port->membase + ALTERA_UART_STATUS_REG) & | 432 | while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & |
418 | ALTERA_UART_STATUS_TRDY_MSK)) | 433 | ALTERA_UART_STATUS_TRDY_MSK)) |
419 | cpu_relax(); | 434 | cpu_relax(); |
420 | 435 | ||
@@ -535,6 +550,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
535 | port->uartclk = platp->uartclk; | 550 | port->uartclk = platp->uartclk; |
536 | port->ops = &altera_uart_ops; | 551 | port->ops = &altera_uart_ops; |
537 | port->flags = ASYNC_BOOT_AUTOCONF; | 552 | port->flags = ASYNC_BOOT_AUTOCONF; |
553 | port->private_data = platp; | ||
538 | 554 | ||
539 | uart_add_one_port(&altera_uart_driver, port); | 555 | uart_add_one_port(&altera_uart_driver, port); |
540 | 556 | ||
diff --git a/include/linux/altera_uart.h b/include/linux/altera_uart.h index 8d441064a30d..c022c82db7ca 100644 --- a/include/linux/altera_uart.h +++ b/include/linux/altera_uart.h | |||
@@ -9,6 +9,7 @@ struct altera_uart_platform_uart { | |||
9 | unsigned long mapbase; /* Physical address base */ | 9 | unsigned long mapbase; /* Physical address base */ |
10 | unsigned int irq; /* Interrupt vector */ | 10 | unsigned int irq; /* Interrupt vector */ |
11 | unsigned int uartclk; /* UART clock rate */ | 11 | unsigned int uartclk; /* UART clock rate */ |
12 | unsigned int bus_shift; /* Bus shift (address stride) */ | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | #endif /* __ALTUART_H */ | 15 | #endif /* __ALTUART_H */ |