ia64/linux-2.6.18-xen.hg

annotate drivers/serial/pmac_zilog.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * linux/drivers/serial/pmac_zilog.c
ian@0 3 *
ian@0 4 * Driver for PowerMac Z85c30 based ESCC cell found in the
ian@0 5 * "macio" ASICs of various PowerMac models
ian@0 6 *
ian@0 7 * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org)
ian@0 8 *
ian@0 9 * Derived from drivers/macintosh/macserial.c by Paul Mackerras
ian@0 10 * and drivers/serial/sunzilog.c by David S. Miller
ian@0 11 *
ian@0 12 * Hrm... actually, I ripped most of sunzilog (Thanks David !) and
ian@0 13 * adapted special tweaks needed for us. I don't think it's worth
ian@0 14 * merging back those though. The DMA code still has to get in
ian@0 15 * and once done, I expect that driver to remain fairly stable in
ian@0 16 * the long term, unless we change the driver model again...
ian@0 17 *
ian@0 18 * This program is free software; you can redistribute it and/or modify
ian@0 19 * it under the terms of the GNU General Public License as published by
ian@0 20 * the Free Software Foundation; either version 2 of the License, or
ian@0 21 * (at your option) any later version.
ian@0 22 *
ian@0 23 * This program is distributed in the hope that it will be useful,
ian@0 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ian@0 26 * GNU General Public License for more details.
ian@0 27 *
ian@0 28 * You should have received a copy of the GNU General Public License
ian@0 29 * along with this program; if not, write to the Free Software
ian@0 30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
ian@0 31 *
ian@0 32 * 2004-08-06 Harald Welte <laforge@gnumonks.org>
ian@0 33 * - Enable BREAK interrupt
ian@0 34 * - Add support for sysreq
ian@0 35 *
ian@0 36 * TODO: - Add DMA support
ian@0 37 * - Defer port shutdown to a few seconds after close
ian@0 38 * - maybe put something right into uap->clk_divisor
ian@0 39 */
ian@0 40
ian@0 41 #undef DEBUG
ian@0 42 #undef DEBUG_HARD
ian@0 43 #undef USE_CTRL_O_SYSRQ
ian@0 44
ian@0 45 #include <linux/module.h>
ian@0 46 #include <linux/tty.h>
ian@0 47
ian@0 48 #include <linux/tty_flip.h>
ian@0 49 #include <linux/major.h>
ian@0 50 #include <linux/string.h>
ian@0 51 #include <linux/fcntl.h>
ian@0 52 #include <linux/mm.h>
ian@0 53 #include <linux/kernel.h>
ian@0 54 #include <linux/delay.h>
ian@0 55 #include <linux/init.h>
ian@0 56 #include <linux/console.h>
ian@0 57 #include <linux/slab.h>
ian@0 58 #include <linux/adb.h>
ian@0 59 #include <linux/pmu.h>
ian@0 60 #include <linux/bitops.h>
ian@0 61 #include <linux/sysrq.h>
ian@0 62 #include <linux/mutex.h>
ian@0 63 #include <asm/sections.h>
ian@0 64 #include <asm/io.h>
ian@0 65 #include <asm/irq.h>
ian@0 66 #include <asm/prom.h>
ian@0 67 #include <asm/machdep.h>
ian@0 68 #include <asm/pmac_feature.h>
ian@0 69 #include <asm/dbdma.h>
ian@0 70 #include <asm/macio.h>
ian@0 71
ian@0 72 #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
ian@0 73 #define SUPPORT_SYSRQ
ian@0 74 #endif
ian@0 75
ian@0 76 #include <linux/serial.h>
ian@0 77 #include <linux/serial_core.h>
ian@0 78
ian@0 79 #include "pmac_zilog.h"
ian@0 80
ian@0 81 /* Not yet implemented */
ian@0 82 #undef HAS_DBDMA
ian@0 83
ian@0 84 static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
ian@0 85 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
ian@0 86 MODULE_DESCRIPTION("Driver for the PowerMac serial ports.");
ian@0 87 MODULE_LICENSE("GPL");
ian@0 88
ian@0 89 #define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg)
ian@0 90
ian@0 91
ian@0 92 /*
ian@0 93 * For the sake of early serial console, we can do a pre-probe
ian@0 94 * (optional) of the ports at rather early boot time.
ian@0 95 */
ian@0 96 static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS];
ian@0 97 static int pmz_ports_count;
ian@0 98 static DEFINE_MUTEX(pmz_irq_mutex);
ian@0 99
ian@0 100 static struct uart_driver pmz_uart_reg = {
ian@0 101 .owner = THIS_MODULE,
ian@0 102 .driver_name = "ttyS",
ian@0 103 .dev_name = "ttyS",
ian@0 104 .major = TTY_MAJOR,
ian@0 105 };
ian@0 106
ian@0 107
ian@0 108 /*
ian@0 109 * Load all registers to reprogram the port
ian@0 110 * This function must only be called when the TX is not busy. The UART
ian@0 111 * port lock must be held and local interrupts disabled.
ian@0 112 */
ian@0 113 static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs)
ian@0 114 {
ian@0 115 int i;
ian@0 116
ian@0 117 if (ZS_IS_ASLEEP(uap))
ian@0 118 return;
ian@0 119
ian@0 120 /* Let pending transmits finish. */
ian@0 121 for (i = 0; i < 1000; i++) {
ian@0 122 unsigned char stat = read_zsreg(uap, R1);
ian@0 123 if (stat & ALL_SNT)
ian@0 124 break;
ian@0 125 udelay(100);
ian@0 126 }
ian@0 127
ian@0 128 ZS_CLEARERR(uap);
ian@0 129 zssync(uap);
ian@0 130 ZS_CLEARFIFO(uap);
ian@0 131 zssync(uap);
ian@0 132 ZS_CLEARERR(uap);
ian@0 133
ian@0 134 /* Disable all interrupts. */
ian@0 135 write_zsreg(uap, R1,
ian@0 136 regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
ian@0 137
ian@0 138 /* Set parity, sync config, stop bits, and clock divisor. */
ian@0 139 write_zsreg(uap, R4, regs[R4]);
ian@0 140
ian@0 141 /* Set misc. TX/RX control bits. */
ian@0 142 write_zsreg(uap, R10, regs[R10]);
ian@0 143
ian@0 144 /* Set TX/RX controls sans the enable bits. */
ian@0 145 write_zsreg(uap, R3, regs[R3] & ~RxENABLE);
ian@0 146 write_zsreg(uap, R5, regs[R5] & ~TxENABLE);
ian@0 147
ian@0 148 /* now set R7 "prime" on ESCC */
ian@0 149 write_zsreg(uap, R15, regs[R15] | EN85C30);
ian@0 150 write_zsreg(uap, R7, regs[R7P]);
ian@0 151
ian@0 152 /* make sure we use R7 "non-prime" on ESCC */
ian@0 153 write_zsreg(uap, R15, regs[R15] & ~EN85C30);
ian@0 154
ian@0 155 /* Synchronous mode config. */
ian@0 156 write_zsreg(uap, R6, regs[R6]);
ian@0 157 write_zsreg(uap, R7, regs[R7]);
ian@0 158
ian@0 159 /* Disable baud generator. */
ian@0 160 write_zsreg(uap, R14, regs[R14] & ~BRENAB);
ian@0 161
ian@0 162 /* Clock mode control. */
ian@0 163 write_zsreg(uap, R11, regs[R11]);
ian@0 164
ian@0 165 /* Lower and upper byte of baud rate generator divisor. */
ian@0 166 write_zsreg(uap, R12, regs[R12]);
ian@0 167 write_zsreg(uap, R13, regs[R13]);
ian@0 168
ian@0 169 /* Now rewrite R14, with BRENAB (if set). */
ian@0 170 write_zsreg(uap, R14, regs[R14]);
ian@0 171
ian@0 172 /* Reset external status interrupts. */
ian@0 173 write_zsreg(uap, R0, RES_EXT_INT);
ian@0 174 write_zsreg(uap, R0, RES_EXT_INT);
ian@0 175
ian@0 176 /* Rewrite R3/R5, this time without enables masked. */
ian@0 177 write_zsreg(uap, R3, regs[R3]);
ian@0 178 write_zsreg(uap, R5, regs[R5]);
ian@0 179
ian@0 180 /* Rewrite R1, this time without IRQ enabled masked. */
ian@0 181 write_zsreg(uap, R1, regs[R1]);
ian@0 182
ian@0 183 /* Enable interrupts */
ian@0 184 write_zsreg(uap, R9, regs[R9]);
ian@0 185 }
ian@0 186
ian@0 187 /*
ian@0 188 * We do like sunzilog to avoid disrupting pending Tx
ian@0 189 * Reprogram the Zilog channel HW registers with the copies found in the
ian@0 190 * software state struct. If the transmitter is busy, we defer this update
ian@0 191 * until the next TX complete interrupt. Else, we do it right now.
ian@0 192 *
ian@0 193 * The UART port lock must be held and local interrupts disabled.
ian@0 194 */
ian@0 195 static void pmz_maybe_update_regs(struct uart_pmac_port *uap)
ian@0 196 {
ian@0 197 if (!ZS_REGS_HELD(uap)) {
ian@0 198 if (ZS_TX_ACTIVE(uap)) {
ian@0 199 uap->flags |= PMACZILOG_FLAG_REGS_HELD;
ian@0 200 } else {
ian@0 201 pmz_debug("pmz: maybe_update_regs: updating\n");
ian@0 202 pmz_load_zsregs(uap, uap->curregs);
ian@0 203 }
ian@0 204 }
ian@0 205 }
ian@0 206
ian@0 207 static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
ian@0 208 struct pt_regs *regs)
ian@0 209 {
ian@0 210 struct tty_struct *tty = NULL;
ian@0 211 unsigned char ch, r1, drop, error, flag;
ian@0 212 int loops = 0;
ian@0 213
ian@0 214 /* The interrupt can be enabled when the port isn't open, typically
ian@0 215 * that happens when using one port is open and the other closed (stale
ian@0 216 * interrupt) or when one port is used as a console.
ian@0 217 */
ian@0 218 if (!ZS_IS_OPEN(uap)) {
ian@0 219 pmz_debug("pmz: draining input\n");
ian@0 220 /* Port is closed, drain input data */
ian@0 221 for (;;) {
ian@0 222 if ((++loops) > 1000)
ian@0 223 goto flood;
ian@0 224 (void)read_zsreg(uap, R1);
ian@0 225 write_zsreg(uap, R0, ERR_RES);
ian@0 226 (void)read_zsdata(uap);
ian@0 227 ch = read_zsreg(uap, R0);
ian@0 228 if (!(ch & Rx_CH_AV))
ian@0 229 break;
ian@0 230 }
ian@0 231 return NULL;
ian@0 232 }
ian@0 233
ian@0 234 /* Sanity check, make sure the old bug is no longer happening */
ian@0 235 if (uap->port.info == NULL || uap->port.info->tty == NULL) {
ian@0 236 WARN_ON(1);
ian@0 237 (void)read_zsdata(uap);
ian@0 238 return NULL;
ian@0 239 }
ian@0 240 tty = uap->port.info->tty;
ian@0 241
ian@0 242 while (1) {
ian@0 243 error = 0;
ian@0 244 drop = 0;
ian@0 245
ian@0 246 r1 = read_zsreg(uap, R1);
ian@0 247 ch = read_zsdata(uap);
ian@0 248
ian@0 249 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
ian@0 250 write_zsreg(uap, R0, ERR_RES);
ian@0 251 zssync(uap);
ian@0 252 }
ian@0 253
ian@0 254 ch &= uap->parity_mask;
ian@0 255 if (ch == 0 && uap->flags & PMACZILOG_FLAG_BREAK) {
ian@0 256 uap->flags &= ~PMACZILOG_FLAG_BREAK;
ian@0 257 }
ian@0 258
ian@0 259 #if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_SERIAL_CORE_CONSOLE)
ian@0 260 #ifdef USE_CTRL_O_SYSRQ
ian@0 261 /* Handle the SysRq ^O Hack */
ian@0 262 if (ch == '\x0f') {
ian@0 263 uap->port.sysrq = jiffies + HZ*5;
ian@0 264 goto next_char;
ian@0 265 }
ian@0 266 #endif /* USE_CTRL_O_SYSRQ */
ian@0 267 if (uap->port.sysrq) {
ian@0 268 int swallow;
ian@0 269 spin_unlock(&uap->port.lock);
ian@0 270 swallow = uart_handle_sysrq_char(&uap->port, ch, regs);
ian@0 271 spin_lock(&uap->port.lock);
ian@0 272 if (swallow)
ian@0 273 goto next_char;
ian@0 274 }
ian@0 275 #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */
ian@0 276
ian@0 277 /* A real serial line, record the character and status. */
ian@0 278 if (drop)
ian@0 279 goto next_char;
ian@0 280
ian@0 281 flag = TTY_NORMAL;
ian@0 282 uap->port.icount.rx++;
ian@0 283
ian@0 284 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) {
ian@0 285 error = 1;
ian@0 286 if (r1 & BRK_ABRT) {
ian@0 287 pmz_debug("pmz: got break !\n");
ian@0 288 r1 &= ~(PAR_ERR | CRC_ERR);
ian@0 289 uap->port.icount.brk++;
ian@0 290 if (uart_handle_break(&uap->port))
ian@0 291 goto next_char;
ian@0 292 }
ian@0 293 else if (r1 & PAR_ERR)
ian@0 294 uap->port.icount.parity++;
ian@0 295 else if (r1 & CRC_ERR)
ian@0 296 uap->port.icount.frame++;
ian@0 297 if (r1 & Rx_OVR)
ian@0 298 uap->port.icount.overrun++;
ian@0 299 r1 &= uap->port.read_status_mask;
ian@0 300 if (r1 & BRK_ABRT)
ian@0 301 flag = TTY_BREAK;
ian@0 302 else if (r1 & PAR_ERR)
ian@0 303 flag = TTY_PARITY;
ian@0 304 else if (r1 & CRC_ERR)
ian@0 305 flag = TTY_FRAME;
ian@0 306 }
ian@0 307
ian@0 308 if (uap->port.ignore_status_mask == 0xff ||
ian@0 309 (r1 & uap->port.ignore_status_mask) == 0) {
ian@0 310 tty_insert_flip_char(tty, ch, flag);
ian@0 311 }
ian@0 312 if (r1 & Rx_OVR)
ian@0 313 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
ian@0 314 next_char:
ian@0 315 /* We can get stuck in an infinite loop getting char 0 when the
ian@0 316 * line is in a wrong HW state, we break that here.
ian@0 317 * When that happens, I disable the receive side of the driver.
ian@0 318 * Note that what I've been experiencing is a real irq loop where
ian@0 319 * I'm getting flooded regardless of the actual port speed.
ian@0 320 * Something stange is going on with the HW
ian@0 321 */
ian@0 322 if ((++loops) > 1000)
ian@0 323 goto flood;
ian@0 324 ch = read_zsreg(uap, R0);
ian@0 325 if (!(ch & Rx_CH_AV))
ian@0 326 break;
ian@0 327 }
ian@0 328
ian@0 329 return tty;
ian@0 330 flood:
ian@0 331 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
ian@0 332 write_zsreg(uap, R1, uap->curregs[R1]);
ian@0 333 zssync(uap);
ian@0 334 dev_err(&uap->dev->ofdev.dev, "pmz: rx irq flood !\n");
ian@0 335 return tty;
ian@0 336 }
ian@0 337
ian@0 338 static void pmz_status_handle(struct uart_pmac_port *uap, struct pt_regs *regs)
ian@0 339 {
ian@0 340 unsigned char status;
ian@0 341
ian@0 342 status = read_zsreg(uap, R0);
ian@0 343 write_zsreg(uap, R0, RES_EXT_INT);
ian@0 344 zssync(uap);
ian@0 345
ian@0 346 if (ZS_IS_OPEN(uap) && ZS_WANTS_MODEM_STATUS(uap)) {
ian@0 347 if (status & SYNC_HUNT)
ian@0 348 uap->port.icount.dsr++;
ian@0 349
ian@0 350 /* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
ian@0 351 * But it does not tell us which bit has changed, we have to keep
ian@0 352 * track of this ourselves.
ian@0 353 * The CTS input is inverted for some reason. -- paulus
ian@0 354 */
ian@0 355 if ((status ^ uap->prev_status) & DCD)
ian@0 356 uart_handle_dcd_change(&uap->port,
ian@0 357 (status & DCD));
ian@0 358 if ((status ^ uap->prev_status) & CTS)
ian@0 359 uart_handle_cts_change(&uap->port,
ian@0 360 !(status & CTS));
ian@0 361
ian@0 362 wake_up_interruptible(&uap->port.info->delta_msr_wait);
ian@0 363 }
ian@0 364
ian@0 365 if (status & BRK_ABRT)
ian@0 366 uap->flags |= PMACZILOG_FLAG_BREAK;
ian@0 367
ian@0 368 uap->prev_status = status;
ian@0 369 }
ian@0 370
ian@0 371 static void pmz_transmit_chars(struct uart_pmac_port *uap)
ian@0 372 {
ian@0 373 struct circ_buf *xmit;
ian@0 374
ian@0 375 if (ZS_IS_ASLEEP(uap))
ian@0 376 return;
ian@0 377 if (ZS_IS_CONS(uap)) {
ian@0 378 unsigned char status = read_zsreg(uap, R0);
ian@0 379
ian@0 380 /* TX still busy? Just wait for the next TX done interrupt.
ian@0 381 *
ian@0 382 * It can occur because of how we do serial console writes. It would
ian@0 383 * be nice to transmit console writes just like we normally would for
ian@0 384 * a TTY line. (ie. buffered and TX interrupt driven). That is not
ian@0 385 * easy because console writes cannot sleep. One solution might be
ian@0 386 * to poll on enough port->xmit space becomming free. -DaveM
ian@0 387 */
ian@0 388 if (!(status & Tx_BUF_EMP))
ian@0 389 return;
ian@0 390 }
ian@0 391
ian@0 392 uap->flags &= ~PMACZILOG_FLAG_TX_ACTIVE;
ian@0 393
ian@0 394 if (ZS_REGS_HELD(uap)) {
ian@0 395 pmz_load_zsregs(uap, uap->curregs);
ian@0 396 uap->flags &= ~PMACZILOG_FLAG_REGS_HELD;
ian@0 397 }
ian@0 398
ian@0 399 if (ZS_TX_STOPPED(uap)) {
ian@0 400 uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED;
ian@0 401 goto ack_tx_int;
ian@0 402 }
ian@0 403
ian@0 404 if (uap->port.x_char) {
ian@0 405 uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
ian@0 406 write_zsdata(uap, uap->port.x_char);
ian@0 407 zssync(uap);
ian@0 408 uap->port.icount.tx++;
ian@0 409 uap->port.x_char = 0;
ian@0 410 return;
ian@0 411 }
ian@0 412
ian@0 413 if (uap->port.info == NULL)
ian@0 414 goto ack_tx_int;
ian@0 415 xmit = &uap->port.info->xmit;
ian@0 416 if (uart_circ_empty(xmit)) {
ian@0 417 uart_write_wakeup(&uap->port);
ian@0 418 goto ack_tx_int;
ian@0 419 }
ian@0 420 if (uart_tx_stopped(&uap->port))
ian@0 421 goto ack_tx_int;
ian@0 422
ian@0 423 uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
ian@0 424 write_zsdata(uap, xmit->buf[xmit->tail]);
ian@0 425 zssync(uap);
ian@0 426
ian@0 427 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
ian@0 428 uap->port.icount.tx++;
ian@0 429
ian@0 430 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
ian@0 431 uart_write_wakeup(&uap->port);
ian@0 432
ian@0 433 return;
ian@0 434
ian@0 435 ack_tx_int:
ian@0 436 write_zsreg(uap, R0, RES_Tx_P);
ian@0 437 zssync(uap);
ian@0 438 }
ian@0 439
ian@0 440 /* Hrm... we register that twice, fixme later.... */
ian@0 441 static irqreturn_t pmz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ian@0 442 {
ian@0 443 struct uart_pmac_port *uap = dev_id;
ian@0 444 struct uart_pmac_port *uap_a;
ian@0 445 struct uart_pmac_port *uap_b;
ian@0 446 int rc = IRQ_NONE;
ian@0 447 struct tty_struct *tty;
ian@0 448 u8 r3;
ian@0 449
ian@0 450 uap_a = pmz_get_port_A(uap);
ian@0 451 uap_b = uap_a->mate;
ian@0 452
ian@0 453 spin_lock(&uap_a->port.lock);
ian@0 454 r3 = read_zsreg(uap_a, R3);
ian@0 455
ian@0 456 #ifdef DEBUG_HARD
ian@0 457 pmz_debug("irq, r3: %x\n", r3);
ian@0 458 #endif
ian@0 459 /* Channel A */
ian@0 460 tty = NULL;
ian@0 461 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
ian@0 462 write_zsreg(uap_a, R0, RES_H_IUS);
ian@0 463 zssync(uap_a);
ian@0 464 if (r3 & CHAEXT)
ian@0 465 pmz_status_handle(uap_a, regs);
ian@0 466 if (r3 & CHARxIP)
ian@0 467 tty = pmz_receive_chars(uap_a, regs);
ian@0 468 if (r3 & CHATxIP)
ian@0 469 pmz_transmit_chars(uap_a);
ian@0 470 rc = IRQ_HANDLED;
ian@0 471 }
ian@0 472 spin_unlock(&uap_a->port.lock);
ian@0 473 if (tty != NULL)
ian@0 474 tty_flip_buffer_push(tty);
ian@0 475
ian@0 476 if (uap_b->node == NULL)
ian@0 477 goto out;
ian@0 478
ian@0 479 spin_lock(&uap_b->port.lock);
ian@0 480 tty = NULL;
ian@0 481 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
ian@0 482 write_zsreg(uap_b, R0, RES_H_IUS);
ian@0 483 zssync(uap_b);
ian@0 484 if (r3 & CHBEXT)
ian@0 485 pmz_status_handle(uap_b, regs);
ian@0 486 if (r3 & CHBRxIP)
ian@0 487 tty = pmz_receive_chars(uap_b, regs);
ian@0 488 if (r3 & CHBTxIP)
ian@0 489 pmz_transmit_chars(uap_b);
ian@0 490 rc = IRQ_HANDLED;
ian@0 491 }
ian@0 492 spin_unlock(&uap_b->port.lock);
ian@0 493 if (tty != NULL)
ian@0 494 tty_flip_buffer_push(tty);
ian@0 495
ian@0 496 out:
ian@0 497 #ifdef DEBUG_HARD
ian@0 498 pmz_debug("irq done.\n");
ian@0 499 #endif
ian@0 500 return rc;
ian@0 501 }
ian@0 502
ian@0 503 /*
ian@0 504 * Peek the status register, lock not held by caller
ian@0 505 */
ian@0 506 static inline u8 pmz_peek_status(struct uart_pmac_port *uap)
ian@0 507 {
ian@0 508 unsigned long flags;
ian@0 509 u8 status;
ian@0 510
ian@0 511 spin_lock_irqsave(&uap->port.lock, flags);
ian@0 512 status = read_zsreg(uap, R0);
ian@0 513 spin_unlock_irqrestore(&uap->port.lock, flags);
ian@0 514
ian@0 515 return status;
ian@0 516 }
ian@0 517
ian@0 518 /*
ian@0 519 * Check if transmitter is empty
ian@0 520 * The port lock is not held.
ian@0 521 */
ian@0 522 static unsigned int pmz_tx_empty(struct uart_port *port)
ian@0 523 {
ian@0 524 struct uart_pmac_port *uap = to_pmz(port);
ian@0 525 unsigned char status;
ian@0 526
ian@0 527 if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
ian@0 528 return TIOCSER_TEMT;
ian@0 529
ian@0 530 status = pmz_peek_status(to_pmz(port));
ian@0 531 if (status & Tx_BUF_EMP)
ian@0 532 return TIOCSER_TEMT;
ian@0 533 return 0;
ian@0 534 }
ian@0 535
ian@0 536 /*
ian@0 537 * Set Modem Control (RTS & DTR) bits
ian@0 538 * The port lock is held and interrupts are disabled.
ian@0 539 * Note: Shall we really filter out RTS on external ports or
ian@0 540 * should that be dealt at higher level only ?
ian@0 541 */
ian@0 542 static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
ian@0 543 {
ian@0 544 struct uart_pmac_port *uap = to_pmz(port);
ian@0 545 unsigned char set_bits, clear_bits;
ian@0 546
ian@0 547 /* Do nothing for irda for now... */
ian@0 548 if (ZS_IS_IRDA(uap))
ian@0 549 return;
ian@0 550 /* We get called during boot with a port not up yet */
ian@0 551 if (ZS_IS_ASLEEP(uap) ||
ian@0 552 !(ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)))
ian@0 553 return;
ian@0 554
ian@0 555 set_bits = clear_bits = 0;
ian@0 556
ian@0 557 if (ZS_IS_INTMODEM(uap)) {
ian@0 558 if (mctrl & TIOCM_RTS)
ian@0 559 set_bits |= RTS;
ian@0 560 else
ian@0 561 clear_bits |= RTS;
ian@0 562 }
ian@0 563 if (mctrl & TIOCM_DTR)
ian@0 564 set_bits |= DTR;
ian@0 565 else
ian@0 566 clear_bits |= DTR;
ian@0 567
ian@0 568 /* NOTE: Not subject to 'transmitter active' rule. */
ian@0 569 uap->curregs[R5] |= set_bits;
ian@0 570 uap->curregs[R5] &= ~clear_bits;
ian@0 571 if (ZS_IS_ASLEEP(uap))
ian@0 572 return;
ian@0 573 write_zsreg(uap, R5, uap->curregs[R5]);
ian@0 574 pmz_debug("pmz_set_mctrl: set bits: %x, clear bits: %x -> %x\n",
ian@0 575 set_bits, clear_bits, uap->curregs[R5]);
ian@0 576 zssync(uap);
ian@0 577 }
ian@0 578
ian@0 579 /*
ian@0 580 * Get Modem Control bits (only the input ones, the core will
ian@0 581 * or that with a cached value of the control ones)
ian@0 582 * The port lock is held and interrupts are disabled.
ian@0 583 */
ian@0 584 static unsigned int pmz_get_mctrl(struct uart_port *port)
ian@0 585 {
ian@0 586 struct uart_pmac_port *uap = to_pmz(port);
ian@0 587 unsigned char status;
ian@0 588 unsigned int ret;
ian@0 589
ian@0 590 if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
ian@0 591 return 0;
ian@0 592
ian@0 593 status = read_zsreg(uap, R0);
ian@0 594
ian@0 595 ret = 0;
ian@0 596 if (status & DCD)
ian@0 597 ret |= TIOCM_CAR;
ian@0 598 if (status & SYNC_HUNT)
ian@0 599 ret |= TIOCM_DSR;
ian@0 600 if (!(status & CTS))
ian@0 601 ret |= TIOCM_CTS;
ian@0 602
ian@0 603 return ret;
ian@0 604 }
ian@0 605
ian@0 606 /*
ian@0 607 * Stop TX side. Dealt like sunzilog at next Tx interrupt,
ian@0 608 * though for DMA, we will have to do a bit more.
ian@0 609 * The port lock is held and interrupts are disabled.
ian@0 610 */
ian@0 611 static void pmz_stop_tx(struct uart_port *port)
ian@0 612 {
ian@0 613 to_pmz(port)->flags |= PMACZILOG_FLAG_TX_STOPPED;
ian@0 614 }
ian@0 615
ian@0 616 /*
ian@0 617 * Kick the Tx side.
ian@0 618 * The port lock is held and interrupts are disabled.
ian@0 619 */
ian@0 620 static void pmz_start_tx(struct uart_port *port)
ian@0 621 {
ian@0 622 struct uart_pmac_port *uap = to_pmz(port);
ian@0 623 unsigned char status;
ian@0 624
ian@0 625 pmz_debug("pmz: start_tx()\n");
ian@0 626
ian@0 627 uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
ian@0 628 uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED;
ian@0 629
ian@0 630 if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
ian@0 631 return;
ian@0 632
ian@0 633 status = read_zsreg(uap, R0);
ian@0 634
ian@0 635 /* TX busy? Just wait for the TX done interrupt. */
ian@0 636 if (!(status & Tx_BUF_EMP))
ian@0 637 return;
ian@0 638
ian@0 639 /* Send the first character to jump-start the TX done
ian@0 640 * IRQ sending engine.
ian@0 641 */
ian@0 642 if (port->x_char) {
ian@0 643 write_zsdata(uap, port->x_char);
ian@0 644 zssync(uap);
ian@0 645 port->icount.tx++;
ian@0 646 port->x_char = 0;
ian@0 647 } else {
ian@0 648 struct circ_buf *xmit = &port->info->xmit;
ian@0 649
ian@0 650 write_zsdata(uap, xmit->buf[xmit->tail]);
ian@0 651 zssync(uap);
ian@0 652 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
ian@0 653 port->icount.tx++;
ian@0 654
ian@0 655 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
ian@0 656 uart_write_wakeup(&uap->port);
ian@0 657 }
ian@0 658 pmz_debug("pmz: start_tx() done.\n");
ian@0 659 }
ian@0 660
ian@0 661 /*
ian@0 662 * Stop Rx side, basically disable emitting of
ian@0 663 * Rx interrupts on the port. We don't disable the rx
ian@0 664 * side of the chip proper though
ian@0 665 * The port lock is held.
ian@0 666 */
ian@0 667 static void pmz_stop_rx(struct uart_port *port)
ian@0 668 {
ian@0 669 struct uart_pmac_port *uap = to_pmz(port);
ian@0 670
ian@0 671 if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
ian@0 672 return;
ian@0 673
ian@0 674 pmz_debug("pmz: stop_rx()()\n");
ian@0 675
ian@0 676 /* Disable all RX interrupts. */
ian@0 677 uap->curregs[R1] &= ~RxINT_MASK;
ian@0 678 pmz_maybe_update_regs(uap);
ian@0 679
ian@0 680 pmz_debug("pmz: stop_rx() done.\n");
ian@0 681 }
ian@0 682
ian@0 683 /*
ian@0 684 * Enable modem status change interrupts
ian@0 685 * The port lock is held.
ian@0 686 */
ian@0 687 static void pmz_enable_ms(struct uart_port *port)
ian@0 688 {
ian@0 689 struct uart_pmac_port *uap = to_pmz(port);
ian@0 690 unsigned char new_reg;
ian@0 691
ian@0 692 if (ZS_IS_IRDA(uap) || uap->node == NULL)
ian@0 693 return;
ian@0 694 new_reg = uap->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
ian@0 695 if (new_reg != uap->curregs[R15]) {
ian@0 696 uap->curregs[R15] = new_reg;
ian@0 697
ian@0 698 if (ZS_IS_ASLEEP(uap))
ian@0 699 return;
ian@0 700 /* NOTE: Not subject to 'transmitter active' rule. */
ian@0 701 write_zsreg(uap, R15, uap->curregs[R15]);
ian@0 702 }
ian@0 703 }
ian@0 704
ian@0 705 /*
ian@0 706 * Control break state emission
ian@0 707 * The port lock is not held.
ian@0 708 */
ian@0 709 static void pmz_break_ctl(struct uart_port *port, int break_state)
ian@0 710 {
ian@0 711 struct uart_pmac_port *uap = to_pmz(port);
ian@0 712 unsigned char set_bits, clear_bits, new_reg;
ian@0 713 unsigned long flags;
ian@0 714
ian@0 715 if (uap->node == NULL)
ian@0 716 return;
ian@0 717 set_bits = clear_bits = 0;
ian@0 718
ian@0 719 if (break_state)
ian@0 720 set_bits |= SND_BRK;
ian@0 721 else
ian@0 722 clear_bits |= SND_BRK;
ian@0 723
ian@0 724 spin_lock_irqsave(&port->lock, flags);
ian@0 725
ian@0 726 new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits;
ian@0 727 if (new_reg != uap->curregs[R5]) {
ian@0 728 uap->curregs[R5] = new_reg;
ian@0 729
ian@0 730 /* NOTE: Not subject to 'transmitter active' rule. */
ian@0 731 if (ZS_IS_ASLEEP(uap))
ian@0 732 return;
ian@0 733 write_zsreg(uap, R5, uap->curregs[R5]);
ian@0 734 }
ian@0 735
ian@0 736 spin_unlock_irqrestore(&port->lock, flags);
ian@0 737 }
ian@0 738
ian@0 739 /*
ian@0 740 * Turn power on or off to the SCC and associated stuff
ian@0 741 * (port drivers, modem, IR port, etc.)
ian@0 742 * Returns the number of milliseconds we should wait before
ian@0 743 * trying to use the port.
ian@0 744 */
ian@0 745 static int pmz_set_scc_power(struct uart_pmac_port *uap, int state)
ian@0 746 {
ian@0 747 int delay = 0;
ian@0 748 int rc;
ian@0 749
ian@0 750 if (state) {
ian@0 751 rc = pmac_call_feature(
ian@0 752 PMAC_FTR_SCC_ENABLE, uap->node, uap->port_type, 1);
ian@0 753 pmz_debug("port power on result: %d\n", rc);
ian@0 754 if (ZS_IS_INTMODEM(uap)) {
ian@0 755 rc = pmac_call_feature(
ian@0 756 PMAC_FTR_MODEM_ENABLE, uap->node, 0, 1);
ian@0 757 delay = 2500; /* wait for 2.5s before using */
ian@0 758 pmz_debug("modem power result: %d\n", rc);
ian@0 759 }
ian@0 760 } else {
ian@0 761 /* TODO: Make that depend on a timer, don't power down
ian@0 762 * immediately
ian@0 763 */
ian@0 764 if (ZS_IS_INTMODEM(uap)) {
ian@0 765 rc = pmac_call_feature(
ian@0 766 PMAC_FTR_MODEM_ENABLE, uap->node, 0, 0);
ian@0 767 pmz_debug("port power off result: %d\n", rc);
ian@0 768 }
ian@0 769 pmac_call_feature(PMAC_FTR_SCC_ENABLE, uap->node, uap->port_type, 0);
ian@0 770 }
ian@0 771 return delay;
ian@0 772 }
ian@0 773
ian@0 774 /*
ian@0 775 * FixZeroBug....Works around a bug in the SCC receving channel.
ian@0 776 * Inspired from Darwin code, 15 Sept. 2000 -DanM
ian@0 777 *
ian@0 778 * The following sequence prevents a problem that is seen with O'Hare ASICs
ian@0 779 * (most versions -- also with some Heathrow and Hydra ASICs) where a zero
ian@0 780 * at the input to the receiver becomes 'stuck' and locks up the receiver.
ian@0 781 * This problem can occur as a result of a zero bit at the receiver input
ian@0 782 * coincident with any of the following events:
ian@0 783 *
ian@0 784 * The SCC is initialized (hardware or software).
ian@0 785 * A framing error is detected.
ian@0 786 * The clocking option changes from synchronous or X1 asynchronous
ian@0 787 * clocking to X16, X32, or X64 asynchronous clocking.
ian@0 788 * The decoding mode is changed among NRZ, NRZI, FM0, or FM1.
ian@0 789 *
ian@0 790 * This workaround attempts to recover from the lockup condition by placing
ian@0 791 * the SCC in synchronous loopback mode with a fast clock before programming
ian@0 792 * any of the asynchronous modes.
ian@0 793 */
ian@0 794 static void pmz_fix_zero_bug_scc(struct uart_pmac_port *uap)
ian@0 795 {
ian@0 796 write_zsreg(uap, 9, ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB);
ian@0 797 zssync(uap);
ian@0 798 udelay(10);
ian@0 799 write_zsreg(uap, 9, (ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB) | NV);
ian@0 800 zssync(uap);
ian@0 801
ian@0 802 write_zsreg(uap, 4, X1CLK | MONSYNC);
ian@0 803 write_zsreg(uap, 3, Rx8);
ian@0 804 write_zsreg(uap, 5, Tx8 | RTS);
ian@0 805 write_zsreg(uap, 9, NV); /* Didn't we already do this? */
ian@0 806 write_zsreg(uap, 11, RCBR | TCBR);
ian@0 807 write_zsreg(uap, 12, 0);
ian@0 808 write_zsreg(uap, 13, 0);
ian@0 809 write_zsreg(uap, 14, (LOOPBAK | BRSRC));
ian@0 810 write_zsreg(uap, 14, (LOOPBAK | BRSRC | BRENAB));
ian@0 811 write_zsreg(uap, 3, Rx8 | RxENABLE);
ian@0 812 write_zsreg(uap, 0, RES_EXT_INT);
ian@0 813 write_zsreg(uap, 0, RES_EXT_INT);
ian@0 814 write_zsreg(uap, 0, RES_EXT_INT); /* to kill some time */
ian@0 815
ian@0 816 /* The channel should be OK now, but it is probably receiving
ian@0 817 * loopback garbage.
ian@0 818 * Switch to asynchronous mode, disable the receiver,
ian@0 819 * and discard everything in the receive buffer.
ian@0 820 */
ian@0 821 write_zsreg(uap, 9, NV);
ian@0 822 write_zsreg(uap, 4, X16CLK | SB_MASK);
ian@0 823 write_zsreg(uap, 3, Rx8);
ian@0 824
ian@0 825 while (read_zsreg(uap, 0) & Rx_CH_AV) {
ian@0 826 (void)read_zsreg(uap, 8);
ian@0 827 write_zsreg(uap, 0, RES_EXT_INT);
ian@0 828 write_zsreg(uap, 0, ERR_RES);
ian@0 829 }
ian@0 830 }
ian@0 831
ian@0 832 /*
ian@0 833 * Real startup routine, powers up the hardware and sets up
ian@0 834 * the SCC. Returns a delay in ms where you need to wait before
ian@0 835 * actually using the port, this is typically the internal modem
ian@0 836 * powerup delay. This routine expect the lock to be taken.
ian@0 837 */
ian@0 838 static int __pmz_startup(struct uart_pmac_port *uap)
ian@0 839 {
ian@0 840 int pwr_delay = 0;
ian@0 841
ian@0 842 memset(&uap->curregs, 0, sizeof(uap->curregs));
ian@0 843
ian@0 844 /* Power up the SCC & underlying hardware (modem/irda) */
ian@0 845 pwr_delay = pmz_set_scc_power(uap, 1);
ian@0 846
ian@0 847 /* Nice buggy HW ... */
ian@0 848 pmz_fix_zero_bug_scc(uap);
ian@0 849
ian@0 850 /* Reset the channel */
ian@0 851 uap->curregs[R9] = 0;
ian@0 852 write_zsreg(uap, 9, ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB);
ian@0 853 zssync(uap);
ian@0 854 udelay(10);
ian@0 855 write_zsreg(uap, 9, 0);
ian@0 856 zssync(uap);
ian@0 857
ian@0 858 /* Clear the interrupt registers */
ian@0 859 write_zsreg(uap, R1, 0);
ian@0 860 write_zsreg(uap, R0, ERR_RES);
ian@0 861 write_zsreg(uap, R0, ERR_RES);
ian@0 862 write_zsreg(uap, R0, RES_H_IUS);
ian@0 863 write_zsreg(uap, R0, RES_H_IUS);
ian@0 864
ian@0 865 /* Setup some valid baud rate */
ian@0 866 uap->curregs[R4] = X16CLK | SB1;
ian@0 867 uap->curregs[R3] = Rx8;
ian@0 868 uap->curregs[R5] = Tx8 | RTS;
ian@0 869 if (!ZS_IS_IRDA(uap))
ian@0 870 uap->curregs[R5] |= DTR;
ian@0 871 uap->curregs[R12] = 0;
ian@0 872 uap->curregs[R13] = 0;
ian@0 873 uap->curregs[R14] = BRENAB;
ian@0 874
ian@0 875 /* Clear handshaking, enable BREAK interrupts */
ian@0 876 uap->curregs[R15] = BRKIE;
ian@0 877
ian@0 878 /* Master interrupt enable */
ian@0 879 uap->curregs[R9] |= NV | MIE;
ian@0 880
ian@0 881 pmz_load_zsregs(uap, uap->curregs);
ian@0 882
ian@0 883 /* Enable receiver and transmitter. */
ian@0 884 write_zsreg(uap, R3, uap->curregs[R3] |= RxENABLE);
ian@0 885 write_zsreg(uap, R5, uap->curregs[R5] |= TxENABLE);
ian@0 886
ian@0 887 /* Remember status for DCD/CTS changes */
ian@0 888 uap->prev_status = read_zsreg(uap, R0);
ian@0 889
ian@0 890
ian@0 891 return pwr_delay;
ian@0 892 }
ian@0 893
ian@0 894 static void pmz_irda_reset(struct uart_pmac_port *uap)
ian@0 895 {
ian@0 896 uap->curregs[R5] |= DTR;
ian@0 897 write_zsreg(uap, R5, uap->curregs[R5]);
ian@0 898 zssync(uap);
ian@0 899 mdelay(110);
ian@0 900 uap->curregs[R5] &= ~DTR;
ian@0 901 write_zsreg(uap, R5, uap->curregs[R5]);
ian@0 902 zssync(uap);
ian@0 903 mdelay(10);
ian@0 904 }
ian@0 905
ian@0 906 /*
ian@0 907 * This is the "normal" startup routine, using the above one
ian@0 908 * wrapped with the lock and doing a schedule delay
ian@0 909 */
ian@0 910 static int pmz_startup(struct uart_port *port)
ian@0 911 {
ian@0 912 struct uart_pmac_port *uap = to_pmz(port);
ian@0 913 unsigned long flags;
ian@0 914 int pwr_delay = 0;
ian@0 915
ian@0 916 pmz_debug("pmz: startup()\n");
ian@0 917
ian@0 918 if (ZS_IS_ASLEEP(uap))
ian@0 919 return -EAGAIN;
ian@0 920 if (uap->node == NULL)
ian@0 921 return -ENODEV;
ian@0 922
ian@0 923 mutex_lock(&pmz_irq_mutex);
ian@0 924
ian@0 925 uap->flags |= PMACZILOG_FLAG_IS_OPEN;
ian@0 926
ian@0 927 /* A console is never powered down. Else, power up and
ian@0 928 * initialize the chip
ian@0 929 */
ian@0 930 if (!ZS_IS_CONS(uap)) {
ian@0 931 spin_lock_irqsave(&port->lock, flags);
ian@0 932 pwr_delay = __pmz_startup(uap);
ian@0 933 spin_unlock_irqrestore(&port->lock, flags);
ian@0 934 }
ian@0 935
ian@0 936 pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON;
ian@0 937 if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, "PowerMac Zilog", uap)) {
ian@0 938 dev_err(&uap->dev->ofdev.dev,
ian@0 939 "Unable to register zs interrupt handler.\n");
ian@0 940 pmz_set_scc_power(uap, 0);
ian@0 941 mutex_unlock(&pmz_irq_mutex);
ian@0 942 return -ENXIO;
ian@0 943 }
ian@0 944
ian@0 945 mutex_unlock(&pmz_irq_mutex);
ian@0 946
ian@0 947 /* Right now, we deal with delay by blocking here, I'll be
ian@0 948 * smarter later on
ian@0 949 */
ian@0 950 if (pwr_delay != 0) {
ian@0 951 pmz_debug("pmz: delaying %d ms\n", pwr_delay);
ian@0 952 msleep(pwr_delay);
ian@0 953 }
ian@0 954
ian@0 955 /* IrDA reset is done now */
ian@0 956 if (ZS_IS_IRDA(uap))
ian@0 957 pmz_irda_reset(uap);
ian@0 958
ian@0 959 /* Enable interrupts emission from the chip */
ian@0 960 spin_lock_irqsave(&port->lock, flags);
ian@0 961 uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
ian@0 962 if (!ZS_IS_EXTCLK(uap))
ian@0 963 uap->curregs[R1] |= EXT_INT_ENAB;
ian@0 964 write_zsreg(uap, R1, uap->curregs[R1]);
ian@0 965 spin_unlock_irqrestore(&port->lock, flags);
ian@0 966
ian@0 967 pmz_debug("pmz: startup() done.\n");
ian@0 968
ian@0 969 return 0;
ian@0 970 }
ian@0 971
ian@0 972 static void pmz_shutdown(struct uart_port *port)
ian@0 973 {
ian@0 974 struct uart_pmac_port *uap = to_pmz(port);
ian@0 975 unsigned long flags;
ian@0 976
ian@0 977 pmz_debug("pmz: shutdown()\n");
ian@0 978
ian@0 979 if (uap->node == NULL)
ian@0 980 return;
ian@0 981
ian@0 982 mutex_lock(&pmz_irq_mutex);
ian@0 983
ian@0 984 /* Release interrupt handler */
ian@0 985 free_irq(uap->port.irq, uap);
ian@0 986
ian@0 987 spin_lock_irqsave(&port->lock, flags);
ian@0 988
ian@0 989 uap->flags &= ~PMACZILOG_FLAG_IS_OPEN;
ian@0 990
ian@0 991 if (!ZS_IS_OPEN(uap->mate))
ian@0 992 pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
ian@0 993
ian@0 994 /* Disable interrupts */
ian@0 995 if (!ZS_IS_ASLEEP(uap)) {
ian@0 996 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
ian@0 997 write_zsreg(uap, R1, uap->curregs[R1]);
ian@0 998 zssync(uap);
ian@0 999 }
ian@0 1000
ian@0 1001 if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
ian@0 1002 spin_unlock_irqrestore(&port->lock, flags);
ian@0 1003 mutex_unlock(&pmz_irq_mutex);
ian@0 1004 return;
ian@0 1005 }
ian@0 1006
ian@0 1007 /* Disable receiver and transmitter. */
ian@0 1008 uap->curregs[R3] &= ~RxENABLE;
ian@0 1009 uap->curregs[R5] &= ~TxENABLE;
ian@0 1010
ian@0 1011 /* Disable all interrupts and BRK assertion. */
ian@0 1012 uap->curregs[R5] &= ~SND_BRK;
ian@0 1013 pmz_maybe_update_regs(uap);
ian@0 1014
ian@0 1015 /* Shut the chip down */
ian@0 1016 pmz_set_scc_power(uap, 0);
ian@0 1017
ian@0 1018 spin_unlock_irqrestore(&port->lock, flags);
ian@0 1019
ian@0 1020 mutex_unlock(&pmz_irq_mutex);
ian@0 1021
ian@0 1022 pmz_debug("pmz: shutdown() done.\n");
ian@0 1023 }
ian@0 1024
ian@0 1025 /* Shared by TTY driver and serial console setup. The port lock is held
ian@0 1026 * and local interrupts are disabled.
ian@0 1027 */
ian@0 1028 static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag,
ian@0 1029 unsigned int iflag, unsigned long baud)
ian@0 1030 {
ian@0 1031 int brg;
ian@0 1032
ian@0 1033
ian@0 1034 /* Switch to external clocking for IrDA high clock rates. That
ian@0 1035 * code could be re-used for Midi interfaces with different
ian@0 1036 * multipliers
ian@0 1037 */
ian@0 1038 if (baud >= 115200 && ZS_IS_IRDA(uap)) {
ian@0 1039 uap->curregs[R4] = X1CLK;
ian@0 1040 uap->curregs[R11] = RCTRxCP | TCTRxCP;
ian@0 1041 uap->curregs[R14] = 0; /* BRG off */
ian@0 1042 uap->curregs[R12] = 0;
ian@0 1043 uap->curregs[R13] = 0;
ian@0 1044 uap->flags |= PMACZILOG_FLAG_IS_EXTCLK;
ian@0 1045 } else {
ian@0 1046 switch (baud) {
ian@0 1047 case ZS_CLOCK/16: /* 230400 */
ian@0 1048 uap->curregs[R4] = X16CLK;
ian@0 1049 uap->curregs[R11] = 0;
ian@0 1050 uap->curregs[R14] = 0;
ian@0 1051 break;
ian@0 1052 case ZS_CLOCK/32: /* 115200 */
ian@0 1053 uap->curregs[R4] = X32CLK;
ian@0 1054 uap->curregs[R11] = 0;
ian@0 1055 uap->curregs[R14] = 0;
ian@0 1056 break;
ian@0 1057 default:
ian@0 1058 uap->curregs[R4] = X16CLK;
ian@0 1059 uap->curregs[R11] = TCBR | RCBR;
ian@0 1060 brg = BPS_TO_BRG(baud, ZS_CLOCK / 16);
ian@0 1061 uap->curregs[R12] = (brg & 255);
ian@0 1062 uap->curregs[R13] = ((brg >> 8) & 255);
ian@0 1063 uap->curregs[R14] = BRENAB;
ian@0 1064 }
ian@0 1065 uap->flags &= ~PMACZILOG_FLAG_IS_EXTCLK;
ian@0 1066 }
ian@0 1067
ian@0 1068 /* Character size, stop bits, and parity. */
ian@0 1069 uap->curregs[3] &= ~RxN_MASK;
ian@0 1070 uap->curregs[5] &= ~TxN_MASK;
ian@0 1071
ian@0 1072 switch (cflag & CSIZE) {
ian@0 1073 case CS5:
ian@0 1074 uap->curregs[3] |= Rx5;
ian@0 1075 uap->curregs[5] |= Tx5;
ian@0 1076 uap->parity_mask = 0x1f;
ian@0 1077 break;
ian@0 1078 case CS6:
ian@0 1079 uap->curregs[3] |= Rx6;
ian@0 1080 uap->curregs[5] |= Tx6;
ian@0 1081 uap->parity_mask = 0x3f;
ian@0 1082 break;
ian@0 1083 case CS7:
ian@0 1084 uap->curregs[3] |= Rx7;
ian@0 1085 uap->curregs[5] |= Tx7;
ian@0 1086 uap->parity_mask = 0x7f;
ian@0 1087 break;
ian@0 1088 case CS8:
ian@0 1089 default:
ian@0 1090 uap->curregs[3] |= Rx8;
ian@0 1091 uap->curregs[5] |= Tx8;
ian@0 1092 uap->parity_mask = 0xff;
ian@0 1093 break;
ian@0 1094 };
ian@0 1095 uap->curregs[4] &= ~(SB_MASK);
ian@0 1096 if (cflag & CSTOPB)
ian@0 1097 uap->curregs[4] |= SB2;
ian@0 1098 else
ian@0 1099 uap->curregs[4] |= SB1;
ian@0 1100 if (cflag & PARENB)
ian@0 1101 uap->curregs[4] |= PAR_ENAB;
ian@0 1102 else
ian@0 1103 uap->curregs[4] &= ~PAR_ENAB;
ian@0 1104 if (!(cflag & PARODD))
ian@0 1105 uap->curregs[4] |= PAR_EVEN;
ian@0 1106 else
ian@0 1107 uap->curregs[4] &= ~PAR_EVEN;
ian@0 1108
ian@0 1109 uap->port.read_status_mask = Rx_OVR;
ian@0 1110 if (iflag & INPCK)
ian@0 1111 uap->port.read_status_mask |= CRC_ERR | PAR_ERR;
ian@0 1112 if (iflag & (BRKINT | PARMRK))
ian@0 1113 uap->port.read_status_mask |= BRK_ABRT;
ian@0 1114
ian@0 1115 uap->port.ignore_status_mask = 0;
ian@0 1116 if (iflag & IGNPAR)
ian@0 1117 uap->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
ian@0 1118 if (iflag & IGNBRK) {
ian@0 1119 uap->port.ignore_status_mask |= BRK_ABRT;
ian@0 1120 if (iflag & IGNPAR)
ian@0 1121 uap->port.ignore_status_mask |= Rx_OVR;
ian@0 1122 }
ian@0 1123
ian@0 1124 if ((cflag & CREAD) == 0)
ian@0 1125 uap->port.ignore_status_mask = 0xff;
ian@0 1126 }
ian@0 1127
ian@0 1128
ian@0 1129 /*
ian@0 1130 * Set the irda codec on the imac to the specified baud rate.
ian@0 1131 */
ian@0 1132 static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
ian@0 1133 {
ian@0 1134 u8 cmdbyte;
ian@0 1135 int t, version;
ian@0 1136
ian@0 1137 switch (*baud) {
ian@0 1138 /* SIR modes */
ian@0 1139 case 2400:
ian@0 1140 cmdbyte = 0x53;
ian@0 1141 break;
ian@0 1142 case 4800:
ian@0 1143 cmdbyte = 0x52;
ian@0 1144 break;
ian@0 1145 case 9600:
ian@0 1146 cmdbyte = 0x51;
ian@0 1147 break;
ian@0 1148 case 19200:
ian@0 1149 cmdbyte = 0x50;
ian@0 1150 break;
ian@0 1151 case 38400:
ian@0 1152 cmdbyte = 0x4f;
ian@0 1153 break;
ian@0 1154 case 57600:
ian@0 1155 cmdbyte = 0x4e;
ian@0 1156 break;
ian@0 1157 case 115200:
ian@0 1158 cmdbyte = 0x4d;
ian@0 1159 break;
ian@0 1160 /* The FIR modes aren't really supported at this point, how
ian@0 1161 * do we select the speed ? via the FCR on KeyLargo ?
ian@0 1162 */
ian@0 1163 case 1152000:
ian@0 1164 cmdbyte = 0;
ian@0 1165 break;
ian@0 1166 case 4000000:
ian@0 1167 cmdbyte = 0;
ian@0 1168 break;
ian@0 1169 default: /* 9600 */
ian@0 1170 cmdbyte = 0x51;
ian@0 1171 *baud = 9600;
ian@0 1172 break;
ian@0 1173 }
ian@0 1174
ian@0 1175 /* Wait for transmitter to drain */
ian@0 1176 t = 10000;
ian@0 1177 while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0
ian@0 1178 || (read_zsreg(uap, R1) & ALL_SNT) == 0) {
ian@0 1179 if (--t <= 0) {
ian@0 1180 dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n");
ian@0 1181 return;
ian@0 1182 }
ian@0 1183 udelay(10);
ian@0 1184 }
ian@0 1185
ian@0 1186 /* Drain the receiver too */
ian@0 1187 t = 100;
ian@0 1188 (void)read_zsdata(uap);
ian@0 1189 (void)read_zsdata(uap);
ian@0 1190 (void)read_zsdata(uap);
ian@0 1191 mdelay(10);
ian@0 1192 while (read_zsreg(uap, R0) & Rx_CH_AV) {
ian@0 1193 read_zsdata(uap);
ian@0 1194 mdelay(10);
ian@0 1195 if (--t <= 0) {
ian@0 1196 dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n");
ian@0 1197 return;
ian@0 1198 }
ian@0 1199 }
ian@0 1200
ian@0 1201 /* Switch to command mode */
ian@0 1202 uap->curregs[R5] |= DTR;
ian@0 1203 write_zsreg(uap, R5, uap->curregs[R5]);
ian@0 1204 zssync(uap);
ian@0 1205 mdelay(1);
ian@0 1206
ian@0 1207 /* Switch SCC to 19200 */
ian@0 1208 pmz_convert_to_zs(uap, CS8, 0, 19200);
ian@0 1209 pmz_load_zsregs(uap, uap->curregs);
ian@0 1210 mdelay(1);
ian@0 1211
ian@0 1212 /* Write get_version command byte */
ian@0 1213 write_zsdata(uap, 1);
ian@0 1214 t = 5000;
ian@0 1215 while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
ian@0 1216 if (--t <= 0) {
ian@0 1217 dev_err(&uap->dev->ofdev.dev,
ian@0 1218 "irda_setup timed out on get_version byte\n");
ian@0 1219 goto out;
ian@0 1220 }
ian@0 1221 udelay(10);
ian@0 1222 }
ian@0 1223 version = read_zsdata(uap);
ian@0 1224
ian@0 1225 if (version < 4) {
ian@0 1226 dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n",
ian@0 1227 version);
ian@0 1228 goto out;
ian@0 1229 }
ian@0 1230
ian@0 1231 /* Send speed mode */
ian@0 1232 write_zsdata(uap, cmdbyte);
ian@0 1233 t = 5000;
ian@0 1234 while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
ian@0 1235 if (--t <= 0) {
ian@0 1236 dev_err(&uap->dev->ofdev.dev,
ian@0 1237 "irda_setup timed out on speed mode byte\n");
ian@0 1238 goto out;
ian@0 1239 }
ian@0 1240 udelay(10);
ian@0 1241 }
ian@0 1242 t = read_zsdata(uap);
ian@0 1243 if (t != cmdbyte)
ian@0 1244 dev_err(&uap->dev->ofdev.dev,
ian@0 1245 "irda_setup speed mode byte = %x (%x)\n", t, cmdbyte);
ian@0 1246
ian@0 1247 dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n",
ian@0 1248 *baud, version);
ian@0 1249
ian@0 1250 (void)read_zsdata(uap);
ian@0 1251 (void)read_zsdata(uap);
ian@0 1252 (void)read_zsdata(uap);
ian@0 1253
ian@0 1254 out:
ian@0 1255 /* Switch back to data mode */
ian@0 1256 uap->curregs[R5] &= ~DTR;
ian@0 1257 write_zsreg(uap, R5, uap->curregs[R5]);
ian@0 1258 zssync(uap);
ian@0 1259
ian@0 1260 (void)read_zsdata(uap);
ian@0 1261 (void)read_zsdata(uap);
ian@0 1262 (void)read_zsdata(uap);
ian@0 1263 }
ian@0 1264
ian@0 1265
ian@0 1266 static void __pmz_set_termios(struct uart_port *port, struct termios *termios,
ian@0 1267 struct termios *old)
ian@0 1268 {
ian@0 1269 struct uart_pmac_port *uap = to_pmz(port);
ian@0 1270 unsigned long baud;
ian@0 1271
ian@0 1272 pmz_debug("pmz: set_termios()\n");
ian@0 1273
ian@0 1274 if (ZS_IS_ASLEEP(uap))
ian@0 1275 return;
ian@0 1276
ian@0 1277 memcpy(&uap->termios_cache, termios, sizeof(struct termios));
ian@0 1278
ian@0 1279 /* XXX Check which revs of machines actually allow 1 and 4Mb speeds
ian@0 1280 * on the IR dongle. Note that the IRTTY driver currently doesn't know
ian@0 1281 * about the FIR mode and high speed modes. So these are unused. For
ian@0 1282 * implementing proper support for these, we should probably add some
ian@0 1283 * DMA as well, at least on the Rx side, which isn't a simple thing
ian@0 1284 * at this point.
ian@0 1285 */
ian@0 1286 if (ZS_IS_IRDA(uap)) {
ian@0 1287 /* Calc baud rate */
ian@0 1288 baud = uart_get_baud_rate(port, termios, old, 1200, 4000000);
ian@0 1289 pmz_debug("pmz: switch IRDA to %ld bauds\n", baud);
ian@0 1290 /* Cet the irda codec to the right rate */
ian@0 1291 pmz_irda_setup(uap, &baud);
ian@0 1292 /* Set final baud rate */
ian@0 1293 pmz_convert_to_zs(uap, termios->c_cflag, termios->c_iflag, baud);
ian@0 1294 pmz_load_zsregs(uap, uap->curregs);
ian@0 1295 zssync(uap);
ian@0 1296 } else {
ian@0 1297 baud = uart_get_baud_rate(port, termios, old, 1200, 230400);
ian@0 1298 pmz_convert_to_zs(uap, termios->c_cflag, termios->c_iflag, baud);
ian@0 1299 /* Make sure modem status interrupts are correctly configured */
ian@0 1300 if (UART_ENABLE_MS(&uap->port, termios->c_cflag)) {
ian@0 1301 uap->curregs[R15] |= DCDIE | SYNCIE | CTSIE;
ian@0 1302 uap->flags |= PMACZILOG_FLAG_MODEM_STATUS;
ian@0 1303 } else {
ian@0 1304 uap->curregs[R15] &= ~(DCDIE | SYNCIE | CTSIE);
ian@0 1305 uap->flags &= ~PMACZILOG_FLAG_MODEM_STATUS;
ian@0 1306 }
ian@0 1307
ian@0 1308 /* Load registers to the chip */
ian@0 1309 pmz_maybe_update_regs(uap);
ian@0 1310 }
ian@0 1311 uart_update_timeout(port, termios->c_cflag, baud);
ian@0 1312
ian@0 1313 pmz_debug("pmz: set_termios() done.\n");
ian@0 1314 }
ian@0 1315
ian@0 1316 /* The port lock is not held. */
ian@0 1317 static void pmz_set_termios(struct uart_port *port, struct termios *termios,
ian@0 1318 struct termios *old)
ian@0 1319 {
ian@0 1320 struct uart_pmac_port *uap = to_pmz(port);
ian@0 1321 unsigned long flags;
ian@0 1322
ian@0 1323 spin_lock_irqsave(&port->lock, flags);
ian@0 1324
ian@0 1325 /* Disable IRQs on the port */
ian@0 1326 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
ian@0 1327 write_zsreg(uap, R1, uap->curregs[R1]);
ian@0 1328
ian@0 1329 /* Setup new port configuration */
ian@0 1330 __pmz_set_termios(port, termios, old);
ian@0 1331
ian@0 1332 /* Re-enable IRQs on the port */
ian@0 1333 if (ZS_IS_OPEN(uap)) {
ian@0 1334 uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
ian@0 1335 if (!ZS_IS_EXTCLK(uap))
ian@0 1336 uap->curregs[R1] |= EXT_INT_ENAB;
ian@0 1337 write_zsreg(uap, R1, uap->curregs[R1]);
ian@0 1338 }
ian@0 1339 spin_unlock_irqrestore(&port->lock, flags);
ian@0 1340 }
ian@0 1341
ian@0 1342 static const char *pmz_type(struct uart_port *port)
ian@0 1343 {
ian@0 1344 struct uart_pmac_port *uap = to_pmz(port);
ian@0 1345
ian@0 1346 if (ZS_IS_IRDA(uap))
ian@0 1347 return "Z85c30 ESCC - Infrared port";
ian@0 1348 else if (ZS_IS_INTMODEM(uap))
ian@0 1349 return "Z85c30 ESCC - Internal modem";
ian@0 1350 return "Z85c30 ESCC - Serial port";
ian@0 1351 }
ian@0 1352
ian@0 1353 /* We do not request/release mappings of the registers here, this
ian@0 1354 * happens at early serial probe time.
ian@0 1355 */
ian@0 1356 static void pmz_release_port(struct uart_port *port)
ian@0 1357 {
ian@0 1358 }
ian@0 1359
ian@0 1360 static int pmz_request_port(struct uart_port *port)
ian@0 1361 {
ian@0 1362 return 0;
ian@0 1363 }
ian@0 1364
ian@0 1365 /* These do not need to do anything interesting either. */
ian@0 1366 static void pmz_config_port(struct uart_port *port, int flags)
ian@0 1367 {
ian@0 1368 }
ian@0 1369
ian@0 1370 /* We do not support letting the user mess with the divisor, IRQ, etc. */
ian@0 1371 static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser)
ian@0 1372 {
ian@0 1373 return -EINVAL;
ian@0 1374 }
ian@0 1375
ian@0 1376 static struct uart_ops pmz_pops = {
ian@0 1377 .tx_empty = pmz_tx_empty,
ian@0 1378 .set_mctrl = pmz_set_mctrl,
ian@0 1379 .get_mctrl = pmz_get_mctrl,
ian@0 1380 .stop_tx = pmz_stop_tx,
ian@0 1381 .start_tx = pmz_start_tx,
ian@0 1382 .stop_rx = pmz_stop_rx,
ian@0 1383 .enable_ms = pmz_enable_ms,
ian@0 1384 .break_ctl = pmz_break_ctl,
ian@0 1385 .startup = pmz_startup,
ian@0 1386 .shutdown = pmz_shutdown,
ian@0 1387 .set_termios = pmz_set_termios,
ian@0 1388 .type = pmz_type,
ian@0 1389 .release_port = pmz_release_port,
ian@0 1390 .request_port = pmz_request_port,
ian@0 1391 .config_port = pmz_config_port,
ian@0 1392 .verify_port = pmz_verify_port,
ian@0 1393 };
ian@0 1394
ian@0 1395 /*
ian@0 1396 * Setup one port structure after probing, HW is down at this point,
ian@0 1397 * Unlike sunzilog, we don't need to pre-init the spinlock as we don't
ian@0 1398 * register our console before uart_add_one_port() is called
ian@0 1399 */
ian@0 1400 static int __init pmz_init_port(struct uart_pmac_port *uap)
ian@0 1401 {
ian@0 1402 struct device_node *np = uap->node;
ian@0 1403 char *conn;
ian@0 1404 struct slot_names_prop {
ian@0 1405 int count;
ian@0 1406 char name[1];
ian@0 1407 } *slots;
ian@0 1408 int len;
ian@0 1409 struct resource r_ports, r_rxdma, r_txdma;
ian@0 1410
ian@0 1411 /*
ian@0 1412 * Request & map chip registers
ian@0 1413 */
ian@0 1414 if (of_address_to_resource(np, 0, &r_ports))
ian@0 1415 return -ENODEV;
ian@0 1416 uap->port.mapbase = r_ports.start;
ian@0 1417 uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
ian@0 1418
ian@0 1419 uap->control_reg = uap->port.membase;
ian@0 1420 uap->data_reg = uap->control_reg + 0x10;
ian@0 1421
ian@0 1422 /*
ian@0 1423 * Request & map DBDMA registers
ian@0 1424 */
ian@0 1425 #ifdef HAS_DBDMA
ian@0 1426 if (of_address_to_resource(np, 1, &r_txdma) == 0 &&
ian@0 1427 of_address_to_resource(np, 2, &r_rxdma) == 0)
ian@0 1428 uap->flags |= PMACZILOG_FLAG_HAS_DMA;
ian@0 1429 #else
ian@0 1430 memset(&r_txdma, 0, sizeof(struct resource));
ian@0 1431 memset(&r_rxdma, 0, sizeof(struct resource));
ian@0 1432 #endif
ian@0 1433 if (ZS_HAS_DMA(uap)) {
ian@0 1434 uap->tx_dma_regs = ioremap(r_txdma.start, 0x100);
ian@0 1435 if (uap->tx_dma_regs == NULL) {
ian@0 1436 uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
ian@0 1437 goto no_dma;
ian@0 1438 }
ian@0 1439 uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100);
ian@0 1440 if (uap->rx_dma_regs == NULL) {
ian@0 1441 iounmap(uap->tx_dma_regs);
ian@0 1442 uap->tx_dma_regs = NULL;
ian@0 1443 uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
ian@0 1444 goto no_dma;
ian@0 1445 }
ian@0 1446 uap->tx_dma_irq = irq_of_parse_and_map(np, 1);
ian@0 1447 uap->rx_dma_irq = irq_of_parse_and_map(np, 2);
ian@0 1448 }
ian@0 1449 no_dma:
ian@0 1450
ian@0 1451 /*
ian@0 1452 * Detect port type
ian@0 1453 */
ian@0 1454 if (device_is_compatible(np, "cobalt"))
ian@0 1455 uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
ian@0 1456 conn = get_property(np, "AAPL,connector", &len);
ian@0 1457 if (conn && (strcmp(conn, "infrared") == 0))
ian@0 1458 uap->flags |= PMACZILOG_FLAG_IS_IRDA;
ian@0 1459 uap->port_type = PMAC_SCC_ASYNC;
ian@0 1460 /* 1999 Powerbook G3 has slot-names property instead */
ian@0 1461 slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
ian@0 1462 if (slots && slots->count > 0) {
ian@0 1463 if (strcmp(slots->name, "IrDA") == 0)
ian@0 1464 uap->flags |= PMACZILOG_FLAG_IS_IRDA;
ian@0 1465 else if (strcmp(slots->name, "Modem") == 0)
ian@0 1466 uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
ian@0 1467 }
ian@0 1468 if (ZS_IS_IRDA(uap))
ian@0 1469 uap->port_type = PMAC_SCC_IRDA;
ian@0 1470 if (ZS_IS_INTMODEM(uap)) {
ian@0 1471 struct device_node* i2c_modem = find_devices("i2c-modem");
ian@0 1472 if (i2c_modem) {
ian@0 1473 char* mid = get_property(i2c_modem, "modem-id", NULL);
ian@0 1474 if (mid) switch(*mid) {
ian@0 1475 case 0x04 :
ian@0 1476 case 0x05 :
ian@0 1477 case 0x07 :
ian@0 1478 case 0x08 :
ian@0 1479 case 0x0b :
ian@0 1480 case 0x0c :
ian@0 1481 uap->port_type = PMAC_SCC_I2S1;
ian@0 1482 }
ian@0 1483 printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n",
ian@0 1484 mid ? (*mid) : 0);
ian@0 1485 } else {
ian@0 1486 printk(KERN_INFO "pmac_zilog: serial modem detected\n");
ian@0 1487 }
ian@0 1488 }
ian@0 1489
ian@0 1490 /*
ian@0 1491 * Init remaining bits of "port" structure
ian@0 1492 */
ian@0 1493 uap->port.iotype = UPIO_MEM;
ian@0 1494 uap->port.irq = irq_of_parse_and_map(np, 0);
ian@0 1495 uap->port.uartclk = ZS_CLOCK;
ian@0 1496 uap->port.fifosize = 1;
ian@0 1497 uap->port.ops = &pmz_pops;
ian@0 1498 uap->port.type = PORT_PMAC_ZILOG;
ian@0 1499 uap->port.flags = 0;
ian@0 1500
ian@0 1501 /* Setup some valid baud rate information in the register
ian@0 1502 * shadows so we don't write crap there before baud rate is
ian@0 1503 * first initialized.
ian@0 1504 */
ian@0 1505 pmz_convert_to_zs(uap, CS8, 0, 9600);
ian@0 1506
ian@0 1507 return 0;
ian@0 1508 }
ian@0 1509
ian@0 1510 /*
ian@0 1511 * Get rid of a port on module removal
ian@0 1512 */
ian@0 1513 static void pmz_dispose_port(struct uart_pmac_port *uap)
ian@0 1514 {
ian@0 1515 struct device_node *np;
ian@0 1516
ian@0 1517 np = uap->node;
ian@0 1518 iounmap(uap->rx_dma_regs);
ian@0 1519 iounmap(uap->tx_dma_regs);
ian@0 1520 iounmap(uap->control_reg);
ian@0 1521 uap->node = NULL;
ian@0 1522 of_node_put(np);
ian@0 1523 memset(uap, 0, sizeof(struct uart_pmac_port));
ian@0 1524 }
ian@0 1525
ian@0 1526 /*
ian@0 1527 * Called upon match with an escc node in the devive-tree.
ian@0 1528 */
ian@0 1529 static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
ian@0 1530 {
ian@0 1531 int i;
ian@0 1532
ian@0 1533 /* Iterate the pmz_ports array to find a matching entry
ian@0 1534 */
ian@0 1535 for (i = 0; i < MAX_ZS_PORTS; i++)
ian@0 1536 if (pmz_ports[i].node == mdev->ofdev.node) {
ian@0 1537 struct uart_pmac_port *uap = &pmz_ports[i];
ian@0 1538
ian@0 1539 uap->dev = mdev;
ian@0 1540 dev_set_drvdata(&mdev->ofdev.dev, uap);
ian@0 1541 if (macio_request_resources(uap->dev, "pmac_zilog"))
ian@0 1542 printk(KERN_WARNING "%s: Failed to request resource"
ian@0 1543 ", port still active\n",
ian@0 1544 uap->node->name);
ian@0 1545 else
ian@0 1546 uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED;
ian@0 1547 return 0;
ian@0 1548 }
ian@0 1549 return -ENODEV;
ian@0 1550 }
ian@0 1551
ian@0 1552 /*
ian@0 1553 * That one should not be called, macio isn't really a hotswap device,
ian@0 1554 * we don't expect one of those serial ports to go away...
ian@0 1555 */
ian@0 1556 static int pmz_detach(struct macio_dev *mdev)
ian@0 1557 {
ian@0 1558 struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
ian@0 1559
ian@0 1560 if (!uap)
ian@0 1561 return -ENODEV;
ian@0 1562
ian@0 1563 if (uap->flags & PMACZILOG_FLAG_RSRC_REQUESTED) {
ian@0 1564 macio_release_resources(uap->dev);
ian@0 1565 uap->flags &= ~PMACZILOG_FLAG_RSRC_REQUESTED;
ian@0 1566 }
ian@0 1567 dev_set_drvdata(&mdev->ofdev.dev, NULL);
ian@0 1568 uap->dev = NULL;
ian@0 1569
ian@0 1570 return 0;
ian@0 1571 }
ian@0 1572
ian@0 1573
ian@0 1574 static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
ian@0 1575 {
ian@0 1576 struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
ian@0 1577 struct uart_state *state;
ian@0 1578 unsigned long flags;
ian@0 1579
ian@0 1580 if (uap == NULL) {
ian@0 1581 printk("HRM... pmz_suspend with NULL uap\n");
ian@0 1582 return 0;
ian@0 1583 }
ian@0 1584
ian@0 1585 if (pm_state.event == mdev->ofdev.dev.power.power_state.event)
ian@0 1586 return 0;
ian@0 1587
ian@0 1588 pmz_debug("suspend, switching to state %d\n", pm_state);
ian@0 1589
ian@0 1590 state = pmz_uart_reg.state + uap->port.line;
ian@0 1591
ian@0 1592 mutex_lock(&pmz_irq_mutex);
ian@0 1593 mutex_lock(&state->mutex);
ian@0 1594
ian@0 1595 spin_lock_irqsave(&uap->port.lock, flags);
ian@0 1596
ian@0 1597 if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) {
ian@0 1598 /* Disable receiver and transmitter. */
ian@0 1599 uap->curregs[R3] &= ~RxENABLE;
ian@0 1600 uap->curregs[R5] &= ~TxENABLE;
ian@0 1601
ian@0 1602 /* Disable all interrupts and BRK assertion. */
ian@0 1603 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
ian@0 1604 uap->curregs[R5] &= ~SND_BRK;
ian@0 1605 pmz_load_zsregs(uap, uap->curregs);
ian@0 1606 uap->flags |= PMACZILOG_FLAG_IS_ASLEEP;
ian@0 1607 mb();
ian@0 1608 }
ian@0 1609
ian@0 1610 spin_unlock_irqrestore(&uap->port.lock, flags);
ian@0 1611
ian@0 1612 if (ZS_IS_OPEN(uap) || ZS_IS_OPEN(uap->mate))
ian@0 1613 if (ZS_IS_ASLEEP(uap->mate) && ZS_IS_IRQ_ON(pmz_get_port_A(uap))) {
ian@0 1614 pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
ian@0 1615 disable_irq(uap->port.irq);
ian@0 1616 }
ian@0 1617
ian@0 1618 if (ZS_IS_CONS(uap))
ian@0 1619 uap->port.cons->flags &= ~CON_ENABLED;
ian@0 1620
ian@0 1621 /* Shut the chip down */
ian@0 1622 pmz_set_scc_power(uap, 0);
ian@0 1623
ian@0 1624 mutex_unlock(&state->mutex);
ian@0 1625 mutex_unlock(&pmz_irq_mutex);
ian@0 1626
ian@0 1627 pmz_debug("suspend, switching complete\n");
ian@0 1628
ian@0 1629 mdev->ofdev.dev.power.power_state = pm_state;
ian@0 1630
ian@0 1631 return 0;
ian@0 1632 }
ian@0 1633
ian@0 1634
ian@0 1635 static int pmz_resume(struct macio_dev *mdev)
ian@0 1636 {
ian@0 1637 struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
ian@0 1638 struct uart_state *state;
ian@0 1639 unsigned long flags;
ian@0 1640 int pwr_delay = 0;
ian@0 1641
ian@0 1642 if (uap == NULL)
ian@0 1643 return 0;
ian@0 1644
ian@0 1645 if (mdev->ofdev.dev.power.power_state.event == PM_EVENT_ON)
ian@0 1646 return 0;
ian@0 1647
ian@0 1648 pmz_debug("resume, switching to state 0\n");
ian@0 1649
ian@0 1650 state = pmz_uart_reg.state + uap->port.line;
ian@0 1651
ian@0 1652 mutex_lock(&pmz_irq_mutex);
ian@0 1653 mutex_lock(&state->mutex);
ian@0 1654
ian@0 1655 spin_lock_irqsave(&uap->port.lock, flags);
ian@0 1656 if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
ian@0 1657 spin_unlock_irqrestore(&uap->port.lock, flags);
ian@0 1658 goto bail;
ian@0 1659 }
ian@0 1660 pwr_delay = __pmz_startup(uap);
ian@0 1661
ian@0 1662 /* Take care of config that may have changed while asleep */
ian@0 1663 __pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
ian@0 1664
ian@0 1665 if (ZS_IS_OPEN(uap)) {
ian@0 1666 /* Enable interrupts */
ian@0 1667 uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
ian@0 1668 if (!ZS_IS_EXTCLK(uap))
ian@0 1669 uap->curregs[R1] |= EXT_INT_ENAB;
ian@0 1670 write_zsreg(uap, R1, uap->curregs[R1]);
ian@0 1671 }
ian@0 1672
ian@0 1673 spin_unlock_irqrestore(&uap->port.lock, flags);
ian@0 1674
ian@0 1675 if (ZS_IS_CONS(uap))
ian@0 1676 uap->port.cons->flags |= CON_ENABLED;
ian@0 1677
ian@0 1678 /* Re-enable IRQ on the controller */
ian@0 1679 if (ZS_IS_OPEN(uap) && !ZS_IS_IRQ_ON(pmz_get_port_A(uap))) {
ian@0 1680 pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON;
ian@0 1681 enable_irq(uap->port.irq);
ian@0 1682 }
ian@0 1683
ian@0 1684 bail:
ian@0 1685 mutex_unlock(&state->mutex);
ian@0 1686 mutex_unlock(&pmz_irq_mutex);
ian@0 1687
ian@0 1688 /* Right now, we deal with delay by blocking here, I'll be
ian@0 1689 * smarter later on
ian@0 1690 */
ian@0 1691 if (pwr_delay != 0) {
ian@0 1692 pmz_debug("pmz: delaying %d ms\n", pwr_delay);
ian@0 1693 msleep(pwr_delay);
ian@0 1694 }
ian@0 1695
ian@0 1696 pmz_debug("resume, switching complete\n");
ian@0 1697
ian@0 1698 mdev->ofdev.dev.power.power_state.event = PM_EVENT_ON;
ian@0 1699
ian@0 1700 return 0;
ian@0 1701 }
ian@0 1702
ian@0 1703 /*
ian@0 1704 * Probe all ports in the system and build the ports array, we register
ian@0 1705 * with the serial layer at this point, the macio-type probing is only
ian@0 1706 * used later to "attach" to the sysfs tree so we get power management
ian@0 1707 * events
ian@0 1708 */
ian@0 1709 static int __init pmz_probe(void)
ian@0 1710 {
ian@0 1711 struct device_node *node_p, *node_a, *node_b, *np;
ian@0 1712 int count = 0;
ian@0 1713 int rc;
ian@0 1714
ian@0 1715 /*
ian@0 1716 * Find all escc chips in the system
ian@0 1717 */
ian@0 1718 node_p = of_find_node_by_name(NULL, "escc");
ian@0 1719 while (node_p) {
ian@0 1720 /*
ian@0 1721 * First get channel A/B node pointers
ian@0 1722 *
ian@0 1723 * TODO: Add routines with proper locking to do that...
ian@0 1724 */
ian@0 1725 node_a = node_b = NULL;
ian@0 1726 for (np = NULL; (np = of_get_next_child(node_p, np)) != NULL;) {
ian@0 1727 if (strncmp(np->name, "ch-a", 4) == 0)
ian@0 1728 node_a = of_node_get(np);
ian@0 1729 else if (strncmp(np->name, "ch-b", 4) == 0)
ian@0 1730 node_b = of_node_get(np);
ian@0 1731 }
ian@0 1732 if (!node_a && !node_b) {
ian@0 1733 of_node_put(node_a);
ian@0 1734 of_node_put(node_b);
ian@0 1735 printk(KERN_ERR "pmac_zilog: missing node %c for escc %s\n",
ian@0 1736 (!node_a) ? 'a' : 'b', node_p->full_name);
ian@0 1737 goto next;
ian@0 1738 }
ian@0 1739
ian@0 1740 /*
ian@0 1741 * Fill basic fields in the port structures
ian@0 1742 */
ian@0 1743 pmz_ports[count].mate = &pmz_ports[count+1];
ian@0 1744 pmz_ports[count+1].mate = &pmz_ports[count];
ian@0 1745 pmz_ports[count].flags = PMACZILOG_FLAG_IS_CHANNEL_A;
ian@0 1746 pmz_ports[count].node = node_a;
ian@0 1747 pmz_ports[count+1].node = node_b;
ian@0 1748 pmz_ports[count].port.line = count;
ian@0 1749 pmz_ports[count+1].port.line = count+1;
ian@0 1750
ian@0 1751 /*
ian@0 1752 * Setup the ports for real
ian@0 1753 */
ian@0 1754 rc = pmz_init_port(&pmz_ports[count]);
ian@0 1755 if (rc == 0 && node_b != NULL)
ian@0 1756 rc = pmz_init_port(&pmz_ports[count+1]);
ian@0 1757 if (rc != 0) {
ian@0 1758 of_node_put(node_a);
ian@0 1759 of_node_put(node_b);
ian@0 1760 memset(&pmz_ports[count], 0, sizeof(struct uart_pmac_port));
ian@0 1761 memset(&pmz_ports[count+1], 0, sizeof(struct uart_pmac_port));
ian@0 1762 goto next;
ian@0 1763 }
ian@0 1764 count += 2;
ian@0 1765 next:
ian@0 1766 node_p = of_find_node_by_name(node_p, "escc");
ian@0 1767 }
ian@0 1768 pmz_ports_count = count;
ian@0 1769
ian@0 1770 return 0;
ian@0 1771 }
ian@0 1772
ian@0 1773 #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
ian@0 1774
ian@0 1775 static void pmz_console_write(struct console *con, const char *s, unsigned int count);
ian@0 1776 static int __init pmz_console_setup(struct console *co, char *options);
ian@0 1777
ian@0 1778 static struct console pmz_console = {
ian@0 1779 .name = "ttyS",
ian@0 1780 .write = pmz_console_write,
ian@0 1781 .device = uart_console_device,
ian@0 1782 .setup = pmz_console_setup,
ian@0 1783 .flags = CON_PRINTBUFFER,
ian@0 1784 .index = -1,
ian@0 1785 .data = &pmz_uart_reg,
ian@0 1786 };
ian@0 1787
ian@0 1788 #define PMACZILOG_CONSOLE &pmz_console
ian@0 1789 #else /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
ian@0 1790 #define PMACZILOG_CONSOLE (NULL)
ian@0 1791 #endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
ian@0 1792
ian@0 1793 /*
ian@0 1794 * Register the driver, console driver and ports with the serial
ian@0 1795 * core
ian@0 1796 */
ian@0 1797 static int __init pmz_register(void)
ian@0 1798 {
ian@0 1799 int i, rc;
ian@0 1800
ian@0 1801 pmz_uart_reg.nr = pmz_ports_count;
ian@0 1802 pmz_uart_reg.cons = PMACZILOG_CONSOLE;
ian@0 1803 pmz_uart_reg.minor = 64;
ian@0 1804
ian@0 1805 /*
ian@0 1806 * Register this driver with the serial core
ian@0 1807 */
ian@0 1808 rc = uart_register_driver(&pmz_uart_reg);
ian@0 1809 if (rc)
ian@0 1810 return rc;
ian@0 1811
ian@0 1812 /*
ian@0 1813 * Register each port with the serial core
ian@0 1814 */
ian@0 1815 for (i = 0; i < pmz_ports_count; i++) {
ian@0 1816 struct uart_pmac_port *uport = &pmz_ports[i];
ian@0 1817 /* NULL node may happen on wallstreet */
ian@0 1818 if (uport->node != NULL)
ian@0 1819 rc = uart_add_one_port(&pmz_uart_reg, &uport->port);
ian@0 1820 if (rc)
ian@0 1821 goto err_out;
ian@0 1822 }
ian@0 1823
ian@0 1824 return 0;
ian@0 1825 err_out:
ian@0 1826 while (i-- > 0) {
ian@0 1827 struct uart_pmac_port *uport = &pmz_ports[i];
ian@0 1828 uart_remove_one_port(&pmz_uart_reg, &uport->port);
ian@0 1829 }
ian@0 1830 uart_unregister_driver(&pmz_uart_reg);
ian@0 1831 return rc;
ian@0 1832 }
ian@0 1833
ian@0 1834 static struct of_device_id pmz_match[] =
ian@0 1835 {
ian@0 1836 {
ian@0 1837 .name = "ch-a",
ian@0 1838 },
ian@0 1839 {
ian@0 1840 .name = "ch-b",
ian@0 1841 },
ian@0 1842 {},
ian@0 1843 };
ian@0 1844 MODULE_DEVICE_TABLE (of, pmz_match);
ian@0 1845
ian@0 1846 static struct macio_driver pmz_driver =
ian@0 1847 {
ian@0 1848 .name = "pmac_zilog",
ian@0 1849 .match_table = pmz_match,
ian@0 1850 .probe = pmz_attach,
ian@0 1851 .remove = pmz_detach,
ian@0 1852 .suspend = pmz_suspend,
ian@0 1853 .resume = pmz_resume,
ian@0 1854 };
ian@0 1855
ian@0 1856 static int __init init_pmz(void)
ian@0 1857 {
ian@0 1858 int rc, i;
ian@0 1859 printk(KERN_INFO "%s\n", version);
ian@0 1860
ian@0 1861 /*
ian@0 1862 * First, we need to do a direct OF-based probe pass. We
ian@0 1863 * do that because we want serial console up before the
ian@0 1864 * macio stuffs calls us back, and since that makes it
ian@0 1865 * easier to pass the proper number of channels to
ian@0 1866 * uart_register_driver()
ian@0 1867 */
ian@0 1868 if (pmz_ports_count == 0)
ian@0 1869 pmz_probe();
ian@0 1870
ian@0 1871 /*
ian@0 1872 * Bail early if no port found
ian@0 1873 */
ian@0 1874 if (pmz_ports_count == 0)
ian@0 1875 return -ENODEV;
ian@0 1876
ian@0 1877 /*
ian@0 1878 * Now we register with the serial layer
ian@0 1879 */
ian@0 1880 rc = pmz_register();
ian@0 1881 if (rc) {
ian@0 1882 printk(KERN_ERR
ian@0 1883 "pmac_zilog: Error registering serial device, disabling pmac_zilog.\n"
ian@0 1884 "pmac_zilog: Did another serial driver already claim the minors?\n");
ian@0 1885 /* effectively "pmz_unprobe()" */
ian@0 1886 for (i=0; i < pmz_ports_count; i++)
ian@0 1887 pmz_dispose_port(&pmz_ports[i]);
ian@0 1888 return rc;
ian@0 1889 }
ian@0 1890
ian@0 1891 /*
ian@0 1892 * Then we register the macio driver itself
ian@0 1893 */
ian@0 1894 return macio_register_driver(&pmz_driver);
ian@0 1895 }
ian@0 1896
ian@0 1897 static void __exit exit_pmz(void)
ian@0 1898 {
ian@0 1899 int i;
ian@0 1900
ian@0 1901 /* Get rid of macio-driver (detach from macio) */
ian@0 1902 macio_unregister_driver(&pmz_driver);
ian@0 1903
ian@0 1904 for (i = 0; i < pmz_ports_count; i++) {
ian@0 1905 struct uart_pmac_port *uport = &pmz_ports[i];
ian@0 1906 if (uport->node != NULL) {
ian@0 1907 uart_remove_one_port(&pmz_uart_reg, &uport->port);
ian@0 1908 pmz_dispose_port(uport);
ian@0 1909 }
ian@0 1910 }
ian@0 1911 /* Unregister UART driver */
ian@0 1912 uart_unregister_driver(&pmz_uart_reg);
ian@0 1913 }
ian@0 1914
ian@0 1915 #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
ian@0 1916
ian@0 1917 static void pmz_console_putchar(struct uart_port *port, int ch)
ian@0 1918 {
ian@0 1919 struct uart_pmac_port *uap = (struct uart_pmac_port *)port;
ian@0 1920
ian@0 1921 /* Wait for the transmit buffer to empty. */
ian@0 1922 while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0)
ian@0 1923 udelay(5);
ian@0 1924 write_zsdata(uap, ch);
ian@0 1925 }
ian@0 1926
ian@0 1927 /*
ian@0 1928 * Print a string to the serial port trying not to disturb
ian@0 1929 * any possible real use of the port...
ian@0 1930 */
ian@0 1931 static void pmz_console_write(struct console *con, const char *s, unsigned int count)
ian@0 1932 {
ian@0 1933 struct uart_pmac_port *uap = &pmz_ports[con->index];
ian@0 1934 unsigned long flags;
ian@0 1935
ian@0 1936 if (ZS_IS_ASLEEP(uap))
ian@0 1937 return;
ian@0 1938 spin_lock_irqsave(&uap->port.lock, flags);
ian@0 1939
ian@0 1940 /* Turn of interrupts and enable the transmitter. */
ian@0 1941 write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB);
ian@0 1942 write_zsreg(uap, R5, uap->curregs[5] | TxENABLE | RTS | DTR);
ian@0 1943
ian@0 1944 uart_console_write(&uap->port, s, count, pmz_console_putchar);
ian@0 1945
ian@0 1946 /* Restore the values in the registers. */
ian@0 1947 write_zsreg(uap, R1, uap->curregs[1]);
ian@0 1948 /* Don't disable the transmitter. */
ian@0 1949
ian@0 1950 spin_unlock_irqrestore(&uap->port.lock, flags);
ian@0 1951 }
ian@0 1952
ian@0 1953 /*
ian@0 1954 * Setup the serial console
ian@0 1955 */
ian@0 1956 static int __init pmz_console_setup(struct console *co, char *options)
ian@0 1957 {
ian@0 1958 struct uart_pmac_port *uap;
ian@0 1959 struct uart_port *port;
ian@0 1960 int baud = 38400;
ian@0 1961 int bits = 8;
ian@0 1962 int parity = 'n';
ian@0 1963 int flow = 'n';
ian@0 1964 unsigned long pwr_delay;
ian@0 1965
ian@0 1966 /*
ian@0 1967 * XServe's default to 57600 bps
ian@0 1968 */
ian@0 1969 if (machine_is_compatible("RackMac1,1")
ian@0 1970 || machine_is_compatible("RackMac1,2")
ian@0 1971 || machine_is_compatible("MacRISC4"))
ian@0 1972 baud = 57600;
ian@0 1973
ian@0 1974 /*
ian@0 1975 * Check whether an invalid uart number has been specified, and
ian@0 1976 * if so, search for the first available port that does have
ian@0 1977 * console support.
ian@0 1978 */
ian@0 1979 if (co->index >= pmz_ports_count)
ian@0 1980 co->index = 0;
ian@0 1981 uap = &pmz_ports[co->index];
ian@0 1982 if (uap->node == NULL)
ian@0 1983 return -ENODEV;
ian@0 1984 port = &uap->port;
ian@0 1985
ian@0 1986 /*
ian@0 1987 * Mark port as beeing a console
ian@0 1988 */
ian@0 1989 uap->flags |= PMACZILOG_FLAG_IS_CONS;
ian@0 1990
ian@0 1991 /*
ian@0 1992 * Temporary fix for uart layer who didn't setup the spinlock yet
ian@0 1993 */
ian@0 1994 spin_lock_init(&port->lock);
ian@0 1995
ian@0 1996 /*
ian@0 1997 * Enable the hardware
ian@0 1998 */
ian@0 1999 pwr_delay = __pmz_startup(uap);
ian@0 2000 if (pwr_delay)
ian@0 2001 mdelay(pwr_delay);
ian@0 2002
ian@0 2003 if (options)
ian@0 2004 uart_parse_options(options, &baud, &parity, &bits, &flow);
ian@0 2005
ian@0 2006 return uart_set_options(port, co, baud, parity, bits, flow);
ian@0 2007 }
ian@0 2008
ian@0 2009 static int __init pmz_console_init(void)
ian@0 2010 {
ian@0 2011 /* Probe ports */
ian@0 2012 pmz_probe();
ian@0 2013
ian@0 2014 /* TODO: Autoprobe console based on OF */
ian@0 2015 /* pmz_console.index = i; */
ian@0 2016 register_console(&pmz_console);
ian@0 2017
ian@0 2018 return 0;
ian@0 2019
ian@0 2020 }
ian@0 2021 console_initcall(pmz_console_init);
ian@0 2022 #endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
ian@0 2023
ian@0 2024 module_init(init_pmz);
ian@0 2025 module_exit(exit_pmz);