diff options
Diffstat (limited to 'drivers/serial/mpc52xx_uart.c')
-rw-r--r-- | drivers/serial/mpc52xx_uart.c | 217 |
1 files changed, 118 insertions, 99 deletions
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index ec36ad78d2fe..3c4d29e59b2c 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -36,7 +36,7 @@ | |||
36 | * DCD. However, the pin multiplexing aren't changed and should be set either | 36 | * DCD. However, the pin multiplexing aren't changed and should be set either |
37 | * by the bootloader or in the platform init code. | 37 | * by the bootloader or in the platform init code. |
38 | * | 38 | * |
39 | * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2, | 39 | * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2, |
40 | * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and | 40 | * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and |
41 | * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly | 41 | * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly |
42 | * fpr the console code : without this 1:1 mapping, at early boot time, when we | 42 | * fpr the console code : without this 1:1 mapping, at early boot time, when we |
@@ -68,11 +68,12 @@ | |||
68 | #include <linux/sysrq.h> | 68 | #include <linux/sysrq.h> |
69 | #include <linux/console.h> | 69 | #include <linux/console.h> |
70 | 70 | ||
71 | #include <asm/delay.h> | 71 | #include <linux/delay.h> |
72 | #include <asm/io.h> | 72 | #include <linux/io.h> |
73 | 73 | ||
74 | #if defined(CONFIG_PPC_MERGE) | 74 | #if defined(CONFIG_PPC_MERGE) |
75 | #include <asm/of_platform.h> | 75 | #include <linux/of.h> |
76 | #include <linux/of_platform.h> | ||
76 | #else | 77 | #else |
77 | #include <linux/platform_device.h> | 78 | #include <linux/platform_device.h> |
78 | #endif | 79 | #endif |
@@ -111,23 +112,27 @@ static void mpc52xx_uart_of_enumerate(void); | |||
111 | #endif | 112 | #endif |
112 | 113 | ||
113 | #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)) | ||
114 | 116 | ||
115 | 117 | ||
116 | /* Forward declaration of the interruption handling routine */ | 118 | /* Forward declaration of the interruption handling routine */ |
117 | static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id); | 119 | static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); |
118 | 120 | ||
119 | 121 | ||
120 | /* Simple macro to test if a port is console or not. This one is taken | 122 | /* Simple macro to test if a port is console or not. This one is taken |
121 | * for serial_core.c and maybe should be moved to serial_core.h ? */ | 123 | * for serial_core.c and maybe should be moved to serial_core.h ? */ |
122 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | 124 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
123 | #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) | 125 | #define uart_console(port) \ |
126 | ((port)->cons && (port)->cons->index == (port)->line) | ||
124 | #else | 127 | #else |
125 | #define uart_console(port) (0) | 128 | #define uart_console(port) (0) |
126 | #endif | 129 | #endif |
127 | 130 | ||
128 | #if defined(CONFIG_PPC_MERGE) | 131 | #if defined(CONFIG_PPC_MERGE) |
129 | static struct of_device_id mpc52xx_uart_of_match[] = { | 132 | static struct of_device_id mpc52xx_uart_of_match[] = { |
130 | { .type = "serial", .compatible = "mpc5200-psc-uart", }, | 133 | { .type = "serial", .compatible = "fsl,mpc5200-psc-uart", }, |
134 | { .type = "serial", .compatible = "mpc5200-psc-uart", }, /* lite5200 */ | ||
135 | { .type = "serial", .compatible = "mpc5200-serial", }, /* efika */ | ||
131 | {}, | 136 | {}, |
132 | }; | 137 | }; |
133 | #endif | 138 | #endif |
@@ -162,7 +167,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port) | |||
162 | { | 167 | { |
163 | /* port->lock taken by caller */ | 168 | /* port->lock taken by caller */ |
164 | port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; | 169 | port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; |
165 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 170 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
166 | } | 171 | } |
167 | 172 | ||
168 | static void | 173 | static void |
@@ -170,7 +175,7 @@ mpc52xx_uart_start_tx(struct uart_port *port) | |||
170 | { | 175 | { |
171 | /* port->lock taken by caller */ | 176 | /* port->lock taken by caller */ |
172 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 177 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; |
173 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 178 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
174 | } | 179 | } |
175 | 180 | ||
176 | static void | 181 | static void |
@@ -184,7 +189,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch) | |||
184 | /* Make sure tx interrupts are on */ | 189 | /* Make sure tx interrupts are on */ |
185 | /* Truly necessary ??? They should be anyway */ | 190 | /* Truly necessary ??? They should be anyway */ |
186 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 191 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; |
187 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 192 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
188 | } | 193 | } |
189 | 194 | ||
190 | spin_unlock_irqrestore(&port->lock, flags); | 195 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -195,7 +200,7 @@ mpc52xx_uart_stop_rx(struct uart_port *port) | |||
195 | { | 200 | { |
196 | /* port->lock taken by caller */ | 201 | /* port->lock taken by caller */ |
197 | port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; | 202 | port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; |
198 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 203 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
199 | } | 204 | } |
200 | 205 | ||
201 | static void | 206 | static void |
@@ -210,10 +215,10 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl) | |||
210 | unsigned long flags; | 215 | unsigned long flags; |
211 | spin_lock_irqsave(&port->lock, flags); | 216 | spin_lock_irqsave(&port->lock, flags); |
212 | 217 | ||
213 | if ( ctl == -1 ) | 218 | if (ctl == -1) |
214 | out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK); | 219 | out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK); |
215 | else | 220 | else |
216 | out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK); | 221 | out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK); |
217 | 222 | ||
218 | spin_unlock_irqrestore(&port->lock, flags); | 223 | spin_unlock_irqrestore(&port->lock, flags); |
219 | } | 224 | } |
@@ -222,6 +227,7 @@ static int | |||
222 | mpc52xx_uart_startup(struct uart_port *port) | 227 | mpc52xx_uart_startup(struct uart_port *port) |
223 | { | 228 | { |
224 | struct mpc52xx_psc __iomem *psc = PSC(port); | 229 | struct mpc52xx_psc __iomem *psc = PSC(port); |
230 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port); | ||
225 | int ret; | 231 | int ret; |
226 | 232 | ||
227 | /* Request IRQ */ | 233 | /* Request IRQ */ |
@@ -231,23 +237,23 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
231 | return ret; | 237 | return ret; |
232 | 238 | ||
233 | /* Reset/activate the port, clear and enable interrupts */ | 239 | /* Reset/activate the port, clear and enable interrupts */ |
234 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 240 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
235 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 241 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
236 | 242 | ||
237 | out_be32(&psc->sicr,0); /* UART mode DCD ignored */ | 243 | out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ |
238 | 244 | ||
239 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ | 245 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ |
240 | 246 | ||
241 | out_8(&psc->rfcntl, 0x00); | 247 | out_8(&fifo->rfcntl, 0x00); |
242 | out_be16(&psc->rfalarm, 0x1ff); | 248 | out_be16(&fifo->rfalarm, 0x1ff); |
243 | out_8(&psc->tfcntl, 0x07); | 249 | out_8(&fifo->tfcntl, 0x07); |
244 | out_be16(&psc->tfalarm, 0x80); | 250 | out_be16(&fifo->tfalarm, 0x80); |
245 | 251 | ||
246 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; | 252 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; |
247 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); | 253 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
248 | 254 | ||
249 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); | 255 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); |
250 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); | 256 | out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); |
251 | 257 | ||
252 | return 0; | 258 | return 0; |
253 | } | 259 | } |
@@ -258,12 +264,12 @@ mpc52xx_uart_shutdown(struct uart_port *port) | |||
258 | struct mpc52xx_psc __iomem *psc = PSC(port); | 264 | struct mpc52xx_psc __iomem *psc = PSC(port); |
259 | 265 | ||
260 | /* Shut down the port. Leave TX active if on a console port */ | 266 | /* Shut down the port. Leave TX active if on a console port */ |
261 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 267 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
262 | if (!uart_console(port)) | 268 | if (!uart_console(port)) |
263 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 269 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
264 | 270 | ||
265 | port->read_status_mask = 0; | 271 | port->read_status_mask = 0; |
266 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); | 272 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
267 | 273 | ||
268 | /* Release interrupt */ | 274 | /* Release interrupt */ |
269 | free_irq(port->irq, port); | 275 | free_irq(port->irq, port); |
@@ -271,7 +277,7 @@ mpc52xx_uart_shutdown(struct uart_port *port) | |||
271 | 277 | ||
272 | static void | 278 | static void |
273 | mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | 279 | mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, |
274 | struct ktermios *old) | 280 | struct ktermios *old) |
275 | { | 281 | { |
276 | struct mpc52xx_psc __iomem *psc = PSC(port); | 282 | struct mpc52xx_psc __iomem *psc = PSC(port); |
277 | unsigned long flags; | 283 | unsigned long flags; |
@@ -283,14 +289,14 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
283 | mr1 = 0; | 289 | mr1 = 0; |
284 | 290 | ||
285 | switch (new->c_cflag & CSIZE) { | 291 | switch (new->c_cflag & CSIZE) { |
286 | case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; | 292 | case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; |
287 | break; | 293 | break; |
288 | case CS6: mr1 |= MPC52xx_PSC_MODE_6_BITS; | 294 | case CS6: mr1 |= MPC52xx_PSC_MODE_6_BITS; |
289 | break; | 295 | break; |
290 | case CS7: mr1 |= MPC52xx_PSC_MODE_7_BITS; | 296 | case CS7: mr1 |= MPC52xx_PSC_MODE_7_BITS; |
291 | break; | 297 | break; |
292 | case CS8: | 298 | case CS8: |
293 | default: mr1 |= MPC52xx_PSC_MODE_8_BITS; | 299 | default: mr1 |= MPC52xx_PSC_MODE_8_BITS; |
294 | } | 300 | } |
295 | 301 | ||
296 | if (new->c_cflag & PARENB) { | 302 | if (new->c_cflag & PARENB) { |
@@ -332,24 +338,24 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
332 | udelay(1); | 338 | udelay(1); |
333 | 339 | ||
334 | if (!j) | 340 | if (!j) |
335 | printk( KERN_ERR "mpc52xx_uart.c: " | 341 | printk(KERN_ERR "mpc52xx_uart.c: " |
336 | "Unable to flush RX & TX fifos in-time in set_termios." | 342 | "Unable to flush RX & TX fifos in-time in set_termios." |
337 | "Some chars may have been lost.\n" ); | 343 | "Some chars may have been lost.\n"); |
338 | 344 | ||
339 | /* Reset the TX & RX */ | 345 | /* Reset the TX & RX */ |
340 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 346 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
341 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 347 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
342 | 348 | ||
343 | /* Send new mode settings */ | 349 | /* Send new mode settings */ |
344 | out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); | 350 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
345 | out_8(&psc->mode,mr1); | 351 | out_8(&psc->mode, mr1); |
346 | out_8(&psc->mode,mr2); | 352 | out_8(&psc->mode, mr2); |
347 | out_8(&psc->ctur,ctr >> 8); | 353 | out_8(&psc->ctur, ctr >> 8); |
348 | out_8(&psc->ctlr,ctr & 0xff); | 354 | out_8(&psc->ctlr, ctr & 0xff); |
349 | 355 | ||
350 | /* Reenable TX & RX */ | 356 | /* Reenable TX & RX */ |
351 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); | 357 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); |
352 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); | 358 | out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); |
353 | 359 | ||
354 | /* We're all set, release the lock */ | 360 | /* We're all set, release the lock */ |
355 | spin_unlock_irqrestore(&port->lock, flags); | 361 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -364,7 +370,8 @@ mpc52xx_uart_type(struct uart_port *port) | |||
364 | static void | 370 | static void |
365 | mpc52xx_uart_release_port(struct uart_port *port) | 371 | mpc52xx_uart_release_port(struct uart_port *port) |
366 | { | 372 | { |
367 | if (port->flags & UPF_IOREMAP) { /* remapped by us ? */ | 373 | /* remapped by us ? */ |
374 | if (port->flags & UPF_IOREMAP) { | ||
368 | iounmap(port->membase); | 375 | iounmap(port->membase); |
369 | port->membase = NULL; | 376 | port->membase = NULL; |
370 | } | 377 | } |
@@ -379,7 +386,7 @@ mpc52xx_uart_request_port(struct uart_port *port) | |||
379 | 386 | ||
380 | if (port->flags & UPF_IOREMAP) /* Need to remap ? */ | 387 | if (port->flags & UPF_IOREMAP) /* Need to remap ? */ |
381 | port->membase = ioremap(port->mapbase, | 388 | port->membase = ioremap(port->mapbase, |
382 | sizeof(struct mpc52xx_psc)); | 389 | sizeof(struct mpc52xx_psc)); |
383 | 390 | ||
384 | if (!port->membase) | 391 | if (!port->membase) |
385 | return -EINVAL; | 392 | return -EINVAL; |
@@ -398,22 +405,22 @@ mpc52xx_uart_request_port(struct uart_port *port) | |||
398 | static void | 405 | static void |
399 | mpc52xx_uart_config_port(struct uart_port *port, int flags) | 406 | mpc52xx_uart_config_port(struct uart_port *port, int flags) |
400 | { | 407 | { |
401 | if ( (flags & UART_CONFIG_TYPE) && | 408 | if ((flags & UART_CONFIG_TYPE) |
402 | (mpc52xx_uart_request_port(port) == 0) ) | 409 | && (mpc52xx_uart_request_port(port) == 0)) |
403 | port->type = PORT_MPC52xx; | 410 | port->type = PORT_MPC52xx; |
404 | } | 411 | } |
405 | 412 | ||
406 | static int | 413 | static int |
407 | mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) | 414 | mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) |
408 | { | 415 | { |
409 | if ( ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx ) | 416 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx) |
410 | return -EINVAL; | 417 | return -EINVAL; |
411 | 418 | ||
412 | if ( (ser->irq != port->irq) || | 419 | if ((ser->irq != port->irq) || |
413 | (ser->io_type != SERIAL_IO_MEM) || | 420 | (ser->io_type != SERIAL_IO_MEM) || |
414 | (ser->baud_base != port->uartclk) || | 421 | (ser->baud_base != port->uartclk) || |
415 | (ser->iomem_base != (void*)port->mapbase) || | 422 | (ser->iomem_base != (void *)port->mapbase) || |
416 | (ser->hub6 != 0 ) ) | 423 | (ser->hub6 != 0)) |
417 | return -EINVAL; | 424 | return -EINVAL; |
418 | 425 | ||
419 | return 0; | 426 | return 0; |
@@ -455,8 +462,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
455 | unsigned short status; | 462 | unsigned short status; |
456 | 463 | ||
457 | /* While we can read, do so ! */ | 464 | /* While we can read, do so ! */ |
458 | while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & | 465 | while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & |
459 | MPC52xx_PSC_SR_RXRDY) { | 466 | MPC52xx_PSC_SR_RXRDY) { |
460 | 467 | ||
461 | /* Get the char */ | 468 | /* Get the char */ |
462 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); | 469 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); |
@@ -474,9 +481,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
474 | flag = TTY_NORMAL; | 481 | flag = TTY_NORMAL; |
475 | port->icount.rx++; | 482 | port->icount.rx++; |
476 | 483 | ||
477 | if ( status & (MPC52xx_PSC_SR_PE | | 484 | if (status & (MPC52xx_PSC_SR_PE | |
478 | MPC52xx_PSC_SR_FE | | 485 | MPC52xx_PSC_SR_FE | |
479 | MPC52xx_PSC_SR_RB) ) { | 486 | MPC52xx_PSC_SR_RB)) { |
480 | 487 | ||
481 | if (status & MPC52xx_PSC_SR_RB) { | 488 | if (status & MPC52xx_PSC_SR_RB) { |
482 | flag = TTY_BREAK; | 489 | flag = TTY_BREAK; |
@@ -487,7 +494,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
487 | flag = TTY_FRAME; | 494 | flag = TTY_FRAME; |
488 | 495 | ||
489 | /* Clear error condition */ | 496 | /* Clear error condition */ |
490 | out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); | 497 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); |
491 | 498 | ||
492 | } | 499 | } |
493 | tty_insert_flip_char(tty, ch, flag); | 500 | tty_insert_flip_char(tty, ch, flag); |
@@ -568,16 +575,16 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
568 | 575 | ||
569 | /* Do we need to receive chars ? */ | 576 | /* Do we need to receive chars ? */ |
570 | /* For this RX interrupts must be on and some chars waiting */ | 577 | /* For this RX interrupts must be on and some chars waiting */ |
571 | if ( status & MPC52xx_PSC_IMR_RXRDY ) | 578 | if (status & MPC52xx_PSC_IMR_RXRDY) |
572 | keepgoing |= mpc52xx_uart_int_rx_chars(port); | 579 | keepgoing |= mpc52xx_uart_int_rx_chars(port); |
573 | 580 | ||
574 | /* Do we need to send chars ? */ | 581 | /* Do we need to send chars ? */ |
575 | /* For this, TX must be ready and TX interrupt enabled */ | 582 | /* For this, TX must be ready and TX interrupt enabled */ |
576 | if ( status & MPC52xx_PSC_IMR_TXRDY ) | 583 | if (status & MPC52xx_PSC_IMR_TXRDY) |
577 | keepgoing |= mpc52xx_uart_int_tx_chars(port); | 584 | keepgoing |= mpc52xx_uart_int_tx_chars(port); |
578 | 585 | ||
579 | /* Limit number of iteration */ | 586 | /* Limit number of iteration */ |
580 | if ( !(--pass) ) | 587 | if (!(--pass)) |
581 | keepgoing = 0; | 588 | keepgoing = 0; |
582 | 589 | ||
583 | } while (keepgoing); | 590 | } while (keepgoing); |
@@ -596,7 +603,7 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
596 | 603 | ||
597 | static void __init | 604 | static void __init |
598 | mpc52xx_console_get_options(struct uart_port *port, | 605 | mpc52xx_console_get_options(struct uart_port *port, |
599 | int *baud, int *parity, int *bits, int *flow) | 606 | int *baud, int *parity, int *bits, int *flow) |
600 | { | 607 | { |
601 | struct mpc52xx_psc __iomem *psc = PSC(port); | 608 | struct mpc52xx_psc __iomem *psc = PSC(port); |
602 | unsigned char mr1; | 609 | unsigned char mr1; |
@@ -604,7 +611,7 @@ mpc52xx_console_get_options(struct uart_port *port, | |||
604 | pr_debug("mpc52xx_console_get_options(port=%p)\n", port); | 611 | pr_debug("mpc52xx_console_get_options(port=%p)\n", port); |
605 | 612 | ||
606 | /* Read the mode registers */ | 613 | /* Read the mode registers */ |
607 | out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); | 614 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
608 | mr1 = in_8(&psc->mode); | 615 | mr1 = in_8(&psc->mode); |
609 | 616 | ||
610 | /* CT{U,L}R are write-only ! */ | 617 | /* CT{U,L}R are write-only ! */ |
@@ -616,11 +623,18 @@ mpc52xx_console_get_options(struct uart_port *port, | |||
616 | 623 | ||
617 | /* Parse them */ | 624 | /* Parse them */ |
618 | switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { | 625 | switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { |
619 | case MPC52xx_PSC_MODE_5_BITS: *bits = 5; break; | 626 | case MPC52xx_PSC_MODE_5_BITS: |
620 | case MPC52xx_PSC_MODE_6_BITS: *bits = 6; break; | 627 | *bits = 5; |
621 | case MPC52xx_PSC_MODE_7_BITS: *bits = 7; break; | 628 | break; |
622 | case MPC52xx_PSC_MODE_8_BITS: | 629 | case MPC52xx_PSC_MODE_6_BITS: |
623 | default: *bits = 8; | 630 | *bits = 6; |
631 | break; | ||
632 | case MPC52xx_PSC_MODE_7_BITS: | ||
633 | *bits = 7; | ||
634 | break; | ||
635 | case MPC52xx_PSC_MODE_8_BITS: | ||
636 | default: | ||
637 | *bits = 8; | ||
624 | } | 638 | } |
625 | 639 | ||
626 | if (mr1 & MPC52xx_PSC_MODE_PARNONE) | 640 | if (mr1 & MPC52xx_PSC_MODE_PARNONE) |
@@ -657,7 +671,7 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | |||
657 | /* Wait the TX buffer to be empty */ | 671 | /* Wait the TX buffer to be empty */ |
658 | j = 20000; /* Maximum wait */ | 672 | j = 20000; /* Maximum wait */ |
659 | while (!(in_be16(&psc->mpc52xx_psc_status) & | 673 | while (!(in_be16(&psc->mpc52xx_psc_status) & |
660 | MPC52xx_PSC_SR_TXEMP) && --j) | 674 | MPC52xx_PSC_SR_TXEMP) && --j) |
661 | udelay(1); | 675 | udelay(1); |
662 | } | 676 | } |
663 | 677 | ||
@@ -730,16 +744,18 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
730 | } | 744 | } |
731 | 745 | ||
732 | pr_debug("Console on ttyPSC%x is %s\n", | 746 | pr_debug("Console on ttyPSC%x is %s\n", |
733 | co->index, mpc52xx_uart_nodes[co->index]->full_name); | 747 | co->index, mpc52xx_uart_nodes[co->index]->full_name); |
734 | 748 | ||
735 | /* Fetch register locations */ | 749 | /* Fetch register locations */ |
736 | if ((ret = of_address_to_resource(np, 0, &res)) != 0) { | 750 | ret = of_address_to_resource(np, 0, &res); |
751 | if (ret) { | ||
737 | pr_debug("Could not get resources for PSC%x\n", co->index); | 752 | pr_debug("Could not get resources for PSC%x\n", co->index); |
738 | return ret; | 753 | return ret; |
739 | } | 754 | } |
740 | 755 | ||
741 | /* Search for bus-frequency property in this node or a parent */ | 756 | /* Search for bus-frequency property in this node or a parent */ |
742 | if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) { | 757 | ipb_freq = mpc52xx_find_ipb_freq(np); |
758 | if (ipb_freq == 0) { | ||
743 | pr_debug("Could not find IPB bus frequency!\n"); | 759 | pr_debug("Could not find IPB bus frequency!\n"); |
744 | return -EINVAL; | 760 | return -EINVAL; |
745 | } | 761 | } |
@@ -757,7 +773,8 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
757 | return -EINVAL; | 773 | return -EINVAL; |
758 | 774 | ||
759 | pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n", | 775 | pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n", |
760 | (void*)port->mapbase, port->membase, port->irq, port->uartclk); | 776 | (void *)port->mapbase, port->membase, |
777 | port->irq, port->uartclk); | ||
761 | 778 | ||
762 | /* Setup the port parameters accoding to options */ | 779 | /* Setup the port parameters accoding to options */ |
763 | if (options) | 780 | if (options) |
@@ -766,7 +783,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
766 | mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); | 783 | mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); |
767 | 784 | ||
768 | pr_debug("Setting console parameters: %i %i%c1 flow=%c\n", | 785 | pr_debug("Setting console parameters: %i %i%c1 flow=%c\n", |
769 | baud, bits, parity, flow); | 786 | baud, bits, parity, flow); |
770 | 787 | ||
771 | return uart_set_options(port, co, baud, parity, bits, flow); | 788 | return uart_set_options(port, co, baud, parity, bits, flow); |
772 | } | 789 | } |
@@ -781,7 +798,7 @@ static struct console mpc52xx_console = { | |||
781 | .device = uart_console_device, | 798 | .device = uart_console_device, |
782 | .setup = mpc52xx_console_setup, | 799 | .setup = mpc52xx_console_setup, |
783 | .flags = CON_PRINTBUFFER, | 800 | .flags = CON_PRINTBUFFER, |
784 | .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0 ) */ | 801 | .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0) */ |
785 | .data = &mpc52xx_uart_driver, | 802 | .data = &mpc52xx_uart_driver, |
786 | }; | 803 | }; |
787 | 804 | ||
@@ -809,7 +826,6 @@ console_initcall(mpc52xx_console_init); | |||
809 | /* ======================================================================== */ | 826 | /* ======================================================================== */ |
810 | 827 | ||
811 | static struct uart_driver mpc52xx_uart_driver = { | 828 | static struct uart_driver mpc52xx_uart_driver = { |
812 | .owner = THIS_MODULE, | ||
813 | .driver_name = "mpc52xx_psc_uart", | 829 | .driver_name = "mpc52xx_psc_uart", |
814 | .dev_name = "ttyPSC", | 830 | .dev_name = "ttyPSC", |
815 | .major = SERIAL_PSC_MAJOR, | 831 | .major = SERIAL_PSC_MAJOR, |
@@ -837,7 +853,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
837 | if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) | 853 | if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) |
838 | return -EINVAL; | 854 | return -EINVAL; |
839 | 855 | ||
840 | if (!mpc52xx_match_psc_function(idx,"uart")) | 856 | if (!mpc52xx_match_psc_function(idx, "uart")) |
841 | return -ENODEV; | 857 | return -ENODEV; |
842 | 858 | ||
843 | /* Init the port structure */ | 859 | /* Init the port structure */ |
@@ -848,13 +864,13 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
848 | port->fifosize = 512; | 864 | port->fifosize = 512; |
849 | port->iotype = UPIO_MEM; | 865 | port->iotype = UPIO_MEM; |
850 | port->flags = UPF_BOOT_AUTOCONF | | 866 | port->flags = UPF_BOOT_AUTOCONF | |
851 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | 867 | (uart_console(port) ? 0 : UPF_IOREMAP); |
852 | port->line = idx; | 868 | port->line = idx; |
853 | port->ops = &mpc52xx_uart_ops; | 869 | port->ops = &mpc52xx_uart_ops; |
854 | port->dev = &dev->dev; | 870 | port->dev = &dev->dev; |
855 | 871 | ||
856 | /* Search for IRQ and mapbase */ | 872 | /* Search for IRQ and mapbase */ |
857 | for (i=0 ; i<dev->num_resources ; i++, res++) { | 873 | for (i = 0 ; i < dev->num_resources ; i++, res++) { |
858 | if (res->flags & IORESOURCE_MEM) | 874 | if (res->flags & IORESOURCE_MEM) |
859 | port->mapbase = res->start; | 875 | port->mapbase = res->start; |
860 | else if (res->flags & IORESOURCE_IRQ) | 876 | else if (res->flags & IORESOURCE_IRQ) |
@@ -866,7 +882,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
866 | /* Add the port to the uart sub-system */ | 882 | /* Add the port to the uart sub-system */ |
867 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | 883 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); |
868 | if (!ret) | 884 | if (!ret) |
869 | platform_set_drvdata(dev, (void*)port); | 885 | platform_set_drvdata(dev, (void *)port); |
870 | 886 | ||
871 | return ret; | 887 | return ret; |
872 | } | 888 | } |
@@ -917,6 +933,7 @@ static struct platform_driver mpc52xx_uart_platform_driver = { | |||
917 | .resume = mpc52xx_uart_resume, | 933 | .resume = mpc52xx_uart_resume, |
918 | #endif | 934 | #endif |
919 | .driver = { | 935 | .driver = { |
936 | .owner = THIS_MODULE, | ||
920 | .name = "mpc52xx-psc", | 937 | .name = "mpc52xx-psc", |
921 | }, | 938 | }, |
922 | }; | 939 | }; |
@@ -946,10 +963,11 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
946 | if (idx >= MPC52xx_PSC_MAXNUM) | 963 | if (idx >= MPC52xx_PSC_MAXNUM) |
947 | return -EINVAL; | 964 | return -EINVAL; |
948 | pr_debug("Found %s assigned to ttyPSC%x\n", | 965 | pr_debug("Found %s assigned to ttyPSC%x\n", |
949 | mpc52xx_uart_nodes[idx]->full_name, idx); | 966 | mpc52xx_uart_nodes[idx]->full_name, idx); |
950 | 967 | ||
951 | /* Search for bus-frequency property in this node or a parent */ | 968 | /* Search for bus-frequency property in this node or a parent */ |
952 | if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) { | 969 | ipb_freq = mpc52xx_find_ipb_freq(op->node); |
970 | if (ipb_freq == 0) { | ||
953 | dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); | 971 | dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); |
954 | return -EINVAL; | 972 | return -EINVAL; |
955 | } | 973 | } |
@@ -962,22 +980,23 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
962 | port->fifosize = 512; | 980 | port->fifosize = 512; |
963 | port->iotype = UPIO_MEM; | 981 | port->iotype = UPIO_MEM; |
964 | port->flags = UPF_BOOT_AUTOCONF | | 982 | port->flags = UPF_BOOT_AUTOCONF | |
965 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | 983 | (uart_console(port) ? 0 : UPF_IOREMAP); |
966 | port->line = idx; | 984 | port->line = idx; |
967 | port->ops = &mpc52xx_uart_ops; | 985 | port->ops = &mpc52xx_uart_ops; |
968 | port->dev = &op->dev; | 986 | port->dev = &op->dev; |
969 | 987 | ||
970 | /* Search for IRQ and mapbase */ | 988 | /* Search for IRQ and mapbase */ |
971 | if ((ret = of_address_to_resource(op->node, 0, &res)) != 0) | 989 | ret = of_address_to_resource(op->node, 0, &res); |
990 | if (ret) | ||
972 | return ret; | 991 | return ret; |
973 | 992 | ||
974 | port->mapbase = res.start; | 993 | port->mapbase = res.start; |
975 | port->irq = irq_of_parse_and_map(op->node, 0); | 994 | port->irq = irq_of_parse_and_map(op->node, 0); |
976 | 995 | ||
977 | dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", | 996 | dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", |
978 | (void*)port->mapbase, port->irq, port->uartclk); | 997 | (void *)port->mapbase, port->irq, port->uartclk); |
979 | 998 | ||
980 | if ((port->irq==NO_IRQ) || !port->mapbase) { | 999 | if ((port->irq == NO_IRQ) || !port->mapbase) { |
981 | printk(KERN_ERR "Could not allocate resources for PSC\n"); | 1000 | printk(KERN_ERR "Could not allocate resources for PSC\n"); |
982 | return -EINVAL; | 1001 | return -EINVAL; |
983 | } | 1002 | } |
@@ -985,7 +1004,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
985 | /* Add the port to the uart sub-system */ | 1004 | /* Add the port to the uart sub-system */ |
986 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | 1005 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); |
987 | if (!ret) | 1006 | if (!ret) |
988 | dev_set_drvdata(&op->dev, (void*)port); | 1007 | dev_set_drvdata(&op->dev, (void *)port); |
989 | 1008 | ||
990 | return ret; | 1009 | return ret; |
991 | } | 1010 | } |
@@ -1048,6 +1067,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx) | |||
1048 | if (idx < 0) | 1067 | if (idx < 0) |
1049 | return; /* No free slot; abort */ | 1068 | return; /* No free slot; abort */ |
1050 | 1069 | ||
1070 | of_node_get(np); | ||
1051 | /* If the slot is already occupied, then swap slots */ | 1071 | /* If the slot is already occupied, then swap slots */ |
1052 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) | 1072 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) |
1053 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; | 1073 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; |
@@ -1057,7 +1077,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx) | |||
1057 | static void | 1077 | static void |
1058 | mpc52xx_uart_of_enumerate(void) | 1078 | mpc52xx_uart_of_enumerate(void) |
1059 | { | 1079 | { |
1060 | static int enum_done = 0; | 1080 | static int enum_done; |
1061 | struct device_node *np; | 1081 | struct device_node *np; |
1062 | const unsigned int *devno; | 1082 | const unsigned int *devno; |
1063 | int i; | 1083 | int i; |
@@ -1071,7 +1091,7 @@ mpc52xx_uart_of_enumerate(void) | |||
1071 | 1091 | ||
1072 | /* Is a particular device number requested? */ | 1092 | /* Is a particular device number requested? */ |
1073 | devno = of_get_property(np, "port-number", NULL); | 1093 | devno = of_get_property(np, "port-number", NULL); |
1074 | mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1); | 1094 | mpc52xx_uart_of_assign(np, devno ? *devno : -1); |
1075 | } | 1095 | } |
1076 | 1096 | ||
1077 | enum_done = 1; | 1097 | enum_done = 1; |
@@ -1079,15 +1099,13 @@ mpc52xx_uart_of_enumerate(void) | |||
1079 | for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { | 1099 | for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { |
1080 | if (mpc52xx_uart_nodes[i]) | 1100 | if (mpc52xx_uart_nodes[i]) |
1081 | pr_debug("%s assigned to ttyPSC%x\n", | 1101 | pr_debug("%s assigned to ttyPSC%x\n", |
1082 | mpc52xx_uart_nodes[i]->full_name, i); | 1102 | mpc52xx_uart_nodes[i]->full_name, i); |
1083 | } | 1103 | } |
1084 | } | 1104 | } |
1085 | 1105 | ||
1086 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); | 1106 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); |
1087 | 1107 | ||
1088 | static struct of_platform_driver mpc52xx_uart_of_driver = { | 1108 | static struct of_platform_driver mpc52xx_uart_of_driver = { |
1089 | .owner = THIS_MODULE, | ||
1090 | .name = "mpc52xx-psc-uart", | ||
1091 | .match_table = mpc52xx_uart_of_match, | 1109 | .match_table = mpc52xx_uart_of_match, |
1092 | .probe = mpc52xx_uart_of_probe, | 1110 | .probe = mpc52xx_uart_of_probe, |
1093 | .remove = mpc52xx_uart_of_remove, | 1111 | .remove = mpc52xx_uart_of_remove, |
@@ -1113,7 +1131,8 @@ mpc52xx_uart_init(void) | |||
1113 | 1131 | ||
1114 | printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n"); | 1132 | printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n"); |
1115 | 1133 | ||
1116 | if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) { | 1134 | ret = uart_register_driver(&mpc52xx_uart_driver); |
1135 | if (ret) { | ||
1117 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", | 1136 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", |
1118 | __FILE__, ret); | 1137 | __FILE__, ret); |
1119 | return ret; | 1138 | return ret; |