diff options
Diffstat (limited to 'drivers/serial/mpc52xx_uart.c')
-rw-r--r-- | drivers/serial/mpc52xx_uart.c | 256 |
1 files changed, 192 insertions, 64 deletions
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 3c4d29e59b2c..7ab73fa4a80f 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -67,7 +67,6 @@ | |||
67 | #include <linux/serial.h> | 67 | #include <linux/serial.h> |
68 | #include <linux/sysrq.h> | 68 | #include <linux/sysrq.h> |
69 | #include <linux/console.h> | 69 | #include <linux/console.h> |
70 | |||
71 | #include <linux/delay.h> | 70 | #include <linux/delay.h> |
72 | #include <linux/io.h> | 71 | #include <linux/io.h> |
73 | 72 | ||
@@ -111,8 +110,8 @@ static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM]; | |||
111 | static void mpc52xx_uart_of_enumerate(void); | 110 | static void mpc52xx_uart_of_enumerate(void); |
112 | #endif | 111 | #endif |
113 | 112 | ||
113 | |||
114 | #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) | 114 | #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) |
115 | #define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) | ||
116 | 115 | ||
117 | 116 | ||
118 | /* Forward declaration of the interruption handling routine */ | 117 | /* Forward declaration of the interruption handling routine */ |
@@ -137,6 +136,162 @@ static struct of_device_id mpc52xx_uart_of_match[] = { | |||
137 | }; | 136 | }; |
138 | #endif | 137 | #endif |
139 | 138 | ||
139 | /* ======================================================================== */ | ||
140 | /* PSC fifo operations for isolating differences between 52xx and 512x */ | ||
141 | /* ======================================================================== */ | ||
142 | |||
143 | struct psc_ops { | ||
144 | void (*fifo_init)(struct uart_port *port); | ||
145 | int (*raw_rx_rdy)(struct uart_port *port); | ||
146 | int (*raw_tx_rdy)(struct uart_port *port); | ||
147 | int (*rx_rdy)(struct uart_port *port); | ||
148 | int (*tx_rdy)(struct uart_port *port); | ||
149 | int (*tx_empty)(struct uart_port *port); | ||
150 | void (*stop_rx)(struct uart_port *port); | ||
151 | void (*start_tx)(struct uart_port *port); | ||
152 | void (*stop_tx)(struct uart_port *port); | ||
153 | void (*rx_clr_irq)(struct uart_port *port); | ||
154 | void (*tx_clr_irq)(struct uart_port *port); | ||
155 | void (*write_char)(struct uart_port *port, unsigned char c); | ||
156 | unsigned char (*read_char)(struct uart_port *port); | ||
157 | void (*cw_disable_ints)(struct uart_port *port); | ||
158 | void (*cw_restore_ints)(struct uart_port *port); | ||
159 | unsigned long (*getuartclk)(void *p); | ||
160 | }; | ||
161 | |||
162 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) | ||
163 | static void mpc52xx_psc_fifo_init(struct uart_port *port) | ||
164 | { | ||
165 | struct mpc52xx_psc __iomem *psc = PSC(port); | ||
166 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); | ||
167 | |||
168 | /* /32 prescaler */ | ||
169 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); | ||
170 | |||
171 | out_8(&fifo->rfcntl, 0x00); | ||
172 | out_be16(&fifo->rfalarm, 0x1ff); | ||
173 | out_8(&fifo->tfcntl, 0x07); | ||
174 | out_be16(&fifo->tfalarm, 0x80); | ||
175 | |||
176 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; | ||
177 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); | ||
178 | } | ||
179 | |||
180 | static int mpc52xx_psc_raw_rx_rdy(struct uart_port *port) | ||
181 | { | ||
182 | return in_be16(&PSC(port)->mpc52xx_psc_status) | ||
183 | & MPC52xx_PSC_SR_RXRDY; | ||
184 | } | ||
185 | |||
186 | static int mpc52xx_psc_raw_tx_rdy(struct uart_port *port) | ||
187 | { | ||
188 | return in_be16(&PSC(port)->mpc52xx_psc_status) | ||
189 | & MPC52xx_PSC_SR_TXRDY; | ||
190 | } | ||
191 | |||
192 | |||
193 | static int mpc52xx_psc_rx_rdy(struct uart_port *port) | ||
194 | { | ||
195 | return in_be16(&PSC(port)->mpc52xx_psc_isr) | ||
196 | & port->read_status_mask | ||
197 | & MPC52xx_PSC_IMR_RXRDY; | ||
198 | } | ||
199 | |||
200 | static int mpc52xx_psc_tx_rdy(struct uart_port *port) | ||
201 | { | ||
202 | return in_be16(&PSC(port)->mpc52xx_psc_isr) | ||
203 | & port->read_status_mask | ||
204 | & MPC52xx_PSC_IMR_TXRDY; | ||
205 | } | ||
206 | |||
207 | static int mpc52xx_psc_tx_empty(struct uart_port *port) | ||
208 | { | ||
209 | return in_be16(&PSC(port)->mpc52xx_psc_status) | ||
210 | & MPC52xx_PSC_SR_TXEMP; | ||
211 | } | ||
212 | |||
213 | static void mpc52xx_psc_start_tx(struct uart_port *port) | ||
214 | { | ||
215 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | ||
216 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
217 | } | ||
218 | |||
219 | static void mpc52xx_psc_stop_tx(struct uart_port *port) | ||
220 | { | ||
221 | port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; | ||
222 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
223 | } | ||
224 | |||
225 | static void mpc52xx_psc_stop_rx(struct uart_port *port) | ||
226 | { | ||
227 | port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; | ||
228 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
229 | } | ||
230 | |||
231 | static void mpc52xx_psc_rx_clr_irq(struct uart_port *port) | ||
232 | { | ||
233 | } | ||
234 | |||
235 | static void mpc52xx_psc_tx_clr_irq(struct uart_port *port) | ||
236 | { | ||
237 | } | ||
238 | |||
239 | static void mpc52xx_psc_write_char(struct uart_port *port, unsigned char c) | ||
240 | { | ||
241 | out_8(&PSC(port)->mpc52xx_psc_buffer_8, c); | ||
242 | } | ||
243 | |||
244 | static unsigned char mpc52xx_psc_read_char(struct uart_port *port) | ||
245 | { | ||
246 | return in_8(&PSC(port)->mpc52xx_psc_buffer_8); | ||
247 | } | ||
248 | |||
249 | static void mpc52xx_psc_cw_disable_ints(struct uart_port *port) | ||
250 | { | ||
251 | out_be16(&PSC(port)->mpc52xx_psc_imr, 0); | ||
252 | } | ||
253 | |||
254 | static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) | ||
255 | { | ||
256 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
257 | } | ||
258 | |||
259 | /* Search for bus-frequency property in this node or a parent */ | ||
260 | static unsigned long mpc52xx_getuartclk(void *p) | ||
261 | { | ||
262 | #if defined(CONFIG_PPC_MERGE) | ||
263 | /* | ||
264 | * 5200 UARTs have a / 32 prescaler | ||
265 | * but the generic serial code assumes 16 | ||
266 | * so return ipb freq / 2 | ||
267 | */ | ||
268 | return mpc52xx_find_ipb_freq(p) / 2; | ||
269 | #else | ||
270 | pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n"); | ||
271 | return NULL; | ||
272 | #endif | ||
273 | } | ||
274 | |||
275 | static struct psc_ops mpc52xx_psc_ops = { | ||
276 | .fifo_init = mpc52xx_psc_fifo_init, | ||
277 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | ||
278 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, | ||
279 | .rx_rdy = mpc52xx_psc_rx_rdy, | ||
280 | .tx_rdy = mpc52xx_psc_tx_rdy, | ||
281 | .tx_empty = mpc52xx_psc_tx_empty, | ||
282 | .stop_rx = mpc52xx_psc_stop_rx, | ||
283 | .start_tx = mpc52xx_psc_start_tx, | ||
284 | .stop_tx = mpc52xx_psc_stop_tx, | ||
285 | .rx_clr_irq = mpc52xx_psc_rx_clr_irq, | ||
286 | .tx_clr_irq = mpc52xx_psc_tx_clr_irq, | ||
287 | .write_char = mpc52xx_psc_write_char, | ||
288 | .read_char = mpc52xx_psc_read_char, | ||
289 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | ||
290 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | ||
291 | .getuartclk = mpc52xx_getuartclk, | ||
292 | }; | ||
293 | |||
294 | static struct psc_ops *psc_ops = &mpc52xx_psc_ops; | ||
140 | 295 | ||
141 | /* ======================================================================== */ | 296 | /* ======================================================================== */ |
142 | /* UART operations */ | 297 | /* UART operations */ |
@@ -145,8 +300,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = { | |||
145 | static unsigned int | 300 | static unsigned int |
146 | mpc52xx_uart_tx_empty(struct uart_port *port) | 301 | mpc52xx_uart_tx_empty(struct uart_port *port) |
147 | { | 302 | { |
148 | int status = in_be16(&PSC(port)->mpc52xx_psc_status); | 303 | return psc_ops->tx_empty(port) ? TIOCSER_TEMT : 0; |
149 | return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0; | ||
150 | } | 304 | } |
151 | 305 | ||
152 | static void | 306 | static void |
@@ -166,16 +320,14 @@ static void | |||
166 | mpc52xx_uart_stop_tx(struct uart_port *port) | 320 | mpc52xx_uart_stop_tx(struct uart_port *port) |
167 | { | 321 | { |
168 | /* port->lock taken by caller */ | 322 | /* port->lock taken by caller */ |
169 | port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; | 323 | psc_ops->stop_tx(port); |
170 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
171 | } | 324 | } |
172 | 325 | ||
173 | static void | 326 | static void |
174 | mpc52xx_uart_start_tx(struct uart_port *port) | 327 | mpc52xx_uart_start_tx(struct uart_port *port) |
175 | { | 328 | { |
176 | /* port->lock taken by caller */ | 329 | /* port->lock taken by caller */ |
177 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 330 | psc_ops->start_tx(port); |
178 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
179 | } | 331 | } |
180 | 332 | ||
181 | static void | 333 | static void |
@@ -188,8 +340,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch) | |||
188 | if (ch) { | 340 | if (ch) { |
189 | /* Make sure tx interrupts are on */ | 341 | /* Make sure tx interrupts are on */ |
190 | /* Truly necessary ??? They should be anyway */ | 342 | /* Truly necessary ??? They should be anyway */ |
191 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 343 | psc_ops->start_tx(port); |
192 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
193 | } | 344 | } |
194 | 345 | ||
195 | spin_unlock_irqrestore(&port->lock, flags); | 346 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -199,8 +350,7 @@ static void | |||
199 | mpc52xx_uart_stop_rx(struct uart_port *port) | 350 | mpc52xx_uart_stop_rx(struct uart_port *port) |
200 | { | 351 | { |
201 | /* port->lock taken by caller */ | 352 | /* port->lock taken by caller */ |
202 | port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; | 353 | psc_ops->stop_rx(port); |
203 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | ||
204 | } | 354 | } |
205 | 355 | ||
206 | static void | 356 | static void |
@@ -227,7 +377,6 @@ static int | |||
227 | mpc52xx_uart_startup(struct uart_port *port) | 377 | mpc52xx_uart_startup(struct uart_port *port) |
228 | { | 378 | { |
229 | struct mpc52xx_psc __iomem *psc = PSC(port); | 379 | struct mpc52xx_psc __iomem *psc = PSC(port); |
230 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port); | ||
231 | int ret; | 380 | int ret; |
232 | 381 | ||
233 | /* Request IRQ */ | 382 | /* Request IRQ */ |
@@ -242,15 +391,7 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
242 | 391 | ||
243 | out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ | 392 | out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ |
244 | 393 | ||
245 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ | 394 | psc_ops->fifo_init(port); |
246 | |||
247 | out_8(&fifo->rfcntl, 0x00); | ||
248 | out_be16(&fifo->rfalarm, 0x1ff); | ||
249 | out_8(&fifo->tfcntl, 0x07); | ||
250 | out_be16(&fifo->tfalarm, 0x80); | ||
251 | |||
252 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; | ||
253 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); | ||
254 | 395 | ||
255 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); | 396 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); |
256 | out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); | 397 | out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); |
@@ -333,8 +474,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
333 | * boot for the console, all stuff is not yet ready to receive at that | 474 | * boot for the console, all stuff is not yet ready to receive at that |
334 | * time and that just makes the kernel oops */ | 475 | * time and that just makes the kernel oops */ |
335 | /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ | 476 | /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ |
336 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && | 477 | while (!mpc52xx_uart_tx_empty(port) && --j) |
337 | --j) | ||
338 | udelay(1); | 478 | udelay(1); |
339 | 479 | ||
340 | if (!j) | 480 | if (!j) |
@@ -462,11 +602,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
462 | unsigned short status; | 602 | unsigned short status; |
463 | 603 | ||
464 | /* While we can read, do so ! */ | 604 | /* While we can read, do so ! */ |
465 | while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & | 605 | while (psc_ops->raw_rx_rdy(port)) { |
466 | MPC52xx_PSC_SR_RXRDY) { | ||
467 | |||
468 | /* Get the char */ | 606 | /* Get the char */ |
469 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); | 607 | ch = psc_ops->read_char(port); |
470 | 608 | ||
471 | /* Handle sysreq char */ | 609 | /* Handle sysreq char */ |
472 | #ifdef SUPPORT_SYSRQ | 610 | #ifdef SUPPORT_SYSRQ |
@@ -481,6 +619,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
481 | flag = TTY_NORMAL; | 619 | flag = TTY_NORMAL; |
482 | port->icount.rx++; | 620 | port->icount.rx++; |
483 | 621 | ||
622 | status = in_be16(&PSC(port)->mpc52xx_psc_status); | ||
623 | |||
484 | if (status & (MPC52xx_PSC_SR_PE | | 624 | if (status & (MPC52xx_PSC_SR_PE | |
485 | MPC52xx_PSC_SR_FE | | 625 | MPC52xx_PSC_SR_FE | |
486 | MPC52xx_PSC_SR_RB)) { | 626 | MPC52xx_PSC_SR_RB)) { |
@@ -510,7 +650,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
510 | 650 | ||
511 | tty_flip_buffer_push(tty); | 651 | tty_flip_buffer_push(tty); |
512 | 652 | ||
513 | return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; | 653 | return psc_ops->raw_rx_rdy(port); |
514 | } | 654 | } |
515 | 655 | ||
516 | static inline int | 656 | static inline int |
@@ -520,7 +660,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) | |||
520 | 660 | ||
521 | /* Process out of band chars */ | 661 | /* Process out of band chars */ |
522 | if (port->x_char) { | 662 | if (port->x_char) { |
523 | out_8(&PSC(port)->mpc52xx_psc_buffer_8, port->x_char); | 663 | psc_ops->write_char(port, port->x_char); |
524 | port->icount.tx++; | 664 | port->icount.tx++; |
525 | port->x_char = 0; | 665 | port->x_char = 0; |
526 | return 1; | 666 | return 1; |
@@ -533,8 +673,8 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) | |||
533 | } | 673 | } |
534 | 674 | ||
535 | /* Send chars */ | 675 | /* Send chars */ |
536 | while (in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXRDY) { | 676 | while (psc_ops->raw_tx_rdy(port)) { |
537 | out_8(&PSC(port)->mpc52xx_psc_buffer_8, xmit->buf[xmit->tail]); | 677 | psc_ops->write_char(port, xmit->buf[xmit->tail]); |
538 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 678 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
539 | port->icount.tx++; | 679 | port->icount.tx++; |
540 | if (uart_circ_empty(xmit)) | 680 | if (uart_circ_empty(xmit)) |
@@ -560,7 +700,6 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
560 | struct uart_port *port = dev_id; | 700 | struct uart_port *port = dev_id; |
561 | unsigned long pass = ISR_PASS_LIMIT; | 701 | unsigned long pass = ISR_PASS_LIMIT; |
562 | unsigned int keepgoing; | 702 | unsigned int keepgoing; |
563 | unsigned short status; | ||
564 | 703 | ||
565 | spin_lock(&port->lock); | 704 | spin_lock(&port->lock); |
566 | 705 | ||
@@ -569,18 +708,12 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
569 | /* If we don't find anything to do, we stop */ | 708 | /* If we don't find anything to do, we stop */ |
570 | keepgoing = 0; | 709 | keepgoing = 0; |
571 | 710 | ||
572 | /* Read status */ | 711 | psc_ops->rx_clr_irq(port); |
573 | status = in_be16(&PSC(port)->mpc52xx_psc_isr); | 712 | if (psc_ops->rx_rdy(port)) |
574 | status &= port->read_status_mask; | ||
575 | |||
576 | /* Do we need to receive chars ? */ | ||
577 | /* For this RX interrupts must be on and some chars waiting */ | ||
578 | if (status & MPC52xx_PSC_IMR_RXRDY) | ||
579 | keepgoing |= mpc52xx_uart_int_rx_chars(port); | 713 | keepgoing |= mpc52xx_uart_int_rx_chars(port); |
580 | 714 | ||
581 | /* Do we need to send chars ? */ | 715 | psc_ops->tx_clr_irq(port); |
582 | /* For this, TX must be ready and TX interrupt enabled */ | 716 | if (psc_ops->tx_rdy(port)) |
583 | if (status & MPC52xx_PSC_IMR_TXRDY) | ||
584 | keepgoing |= mpc52xx_uart_int_tx_chars(port); | 717 | keepgoing |= mpc52xx_uart_int_tx_chars(port); |
585 | 718 | ||
586 | /* Limit number of iteration */ | 719 | /* Limit number of iteration */ |
@@ -647,36 +780,33 @@ static void | |||
647 | mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | 780 | mpc52xx_console_write(struct console *co, const char *s, unsigned int count) |
648 | { | 781 | { |
649 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; | 782 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; |
650 | struct mpc52xx_psc __iomem *psc = PSC(port); | ||
651 | unsigned int i, j; | 783 | unsigned int i, j; |
652 | 784 | ||
653 | /* Disable interrupts */ | 785 | /* Disable interrupts */ |
654 | out_be16(&psc->mpc52xx_psc_imr, 0); | 786 | psc_ops->cw_disable_ints(port); |
655 | 787 | ||
656 | /* Wait the TX buffer to be empty */ | 788 | /* Wait the TX buffer to be empty */ |
657 | j = 5000000; /* Maximum wait */ | 789 | j = 5000000; /* Maximum wait */ |
658 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && | 790 | while (!mpc52xx_uart_tx_empty(port) && --j) |
659 | --j) | ||
660 | udelay(1); | 791 | udelay(1); |
661 | 792 | ||
662 | /* Write all the chars */ | 793 | /* Write all the chars */ |
663 | for (i = 0; i < count; i++, s++) { | 794 | for (i = 0; i < count; i++, s++) { |
664 | /* Line return handling */ | 795 | /* Line return handling */ |
665 | if (*s == '\n') | 796 | if (*s == '\n') |
666 | out_8(&psc->mpc52xx_psc_buffer_8, '\r'); | 797 | psc_ops->write_char(port, '\r'); |
667 | 798 | ||
668 | /* Send the char */ | 799 | /* Send the char */ |
669 | out_8(&psc->mpc52xx_psc_buffer_8, *s); | 800 | psc_ops->write_char(port, *s); |
670 | 801 | ||
671 | /* Wait the TX buffer to be empty */ | 802 | /* Wait the TX buffer to be empty */ |
672 | j = 20000; /* Maximum wait */ | 803 | j = 20000; /* Maximum wait */ |
673 | while (!(in_be16(&psc->mpc52xx_psc_status) & | 804 | while (!mpc52xx_uart_tx_empty(port) && --j) |
674 | MPC52xx_PSC_SR_TXEMP) && --j) | ||
675 | udelay(1); | 805 | udelay(1); |
676 | } | 806 | } |
677 | 807 | ||
678 | /* Restore interrupt state */ | 808 | /* Restore interrupt state */ |
679 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); | 809 | psc_ops->cw_restore_ints(port); |
680 | } | 810 | } |
681 | 811 | ||
682 | #if !defined(CONFIG_PPC_MERGE) | 812 | #if !defined(CONFIG_PPC_MERGE) |
@@ -721,7 +851,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
721 | { | 851 | { |
722 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; | 852 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; |
723 | struct device_node *np = mpc52xx_uart_nodes[co->index]; | 853 | struct device_node *np = mpc52xx_uart_nodes[co->index]; |
724 | unsigned int ipb_freq; | 854 | unsigned int uartclk; |
725 | struct resource res; | 855 | struct resource res; |
726 | int ret; | 856 | int ret; |
727 | 857 | ||
@@ -753,17 +883,16 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
753 | return ret; | 883 | return ret; |
754 | } | 884 | } |
755 | 885 | ||
756 | /* Search for bus-frequency property in this node or a parent */ | 886 | uartclk = psc_ops->getuartclk(np); |
757 | ipb_freq = mpc52xx_find_ipb_freq(np); | 887 | if (uartclk == 0) { |
758 | if (ipb_freq == 0) { | 888 | pr_debug("Could not find uart clock frequency!\n"); |
759 | pr_debug("Could not find IPB bus frequency!\n"); | ||
760 | return -EINVAL; | 889 | return -EINVAL; |
761 | } | 890 | } |
762 | 891 | ||
763 | /* Basic port init. Needed since we use some uart_??? func before | 892 | /* Basic port init. Needed since we use some uart_??? func before |
764 | * real init for early access */ | 893 | * real init for early access */ |
765 | spin_lock_init(&port->lock); | 894 | spin_lock_init(&port->lock); |
766 | port->uartclk = ipb_freq / 2; | 895 | port->uartclk = uartclk; |
767 | port->ops = &mpc52xx_uart_ops; | 896 | port->ops = &mpc52xx_uart_ops; |
768 | port->mapbase = res.start; | 897 | port->mapbase = res.start; |
769 | port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc)); | 898 | port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc)); |
@@ -949,7 +1078,7 @@ static int __devinit | |||
949 | mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | 1078 | mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) |
950 | { | 1079 | { |
951 | int idx = -1; | 1080 | int idx = -1; |
952 | unsigned int ipb_freq; | 1081 | unsigned int uartclk; |
953 | struct uart_port *port = NULL; | 1082 | struct uart_port *port = NULL; |
954 | struct resource res; | 1083 | struct resource res; |
955 | int ret; | 1084 | int ret; |
@@ -965,10 +1094,9 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
965 | pr_debug("Found %s assigned to ttyPSC%x\n", | 1094 | pr_debug("Found %s assigned to ttyPSC%x\n", |
966 | mpc52xx_uart_nodes[idx]->full_name, idx); | 1095 | mpc52xx_uart_nodes[idx]->full_name, idx); |
967 | 1096 | ||
968 | /* Search for bus-frequency property in this node or a parent */ | 1097 | uartclk = psc_ops->getuartclk(op->node); |
969 | ipb_freq = mpc52xx_find_ipb_freq(op->node); | 1098 | if (uartclk == 0) { |
970 | if (ipb_freq == 0) { | 1099 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); |
971 | dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); | ||
972 | return -EINVAL; | 1100 | return -EINVAL; |
973 | } | 1101 | } |
974 | 1102 | ||
@@ -976,7 +1104,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
976 | port = &mpc52xx_uart_ports[idx]; | 1104 | port = &mpc52xx_uart_ports[idx]; |
977 | 1105 | ||
978 | spin_lock_init(&port->lock); | 1106 | spin_lock_init(&port->lock); |
979 | port->uartclk = ipb_freq / 2; | 1107 | port->uartclk = uartclk; |
980 | port->fifosize = 512; | 1108 | port->fifosize = 512; |
981 | port->iotype = UPIO_MEM; | 1109 | port->iotype = UPIO_MEM; |
982 | port->flags = UPF_BOOT_AUTOCONF | | 1110 | port->flags = UPF_BOOT_AUTOCONF | |