Mercurial > hg > aboriginal
changeset 857:eee8e9fcb1dd
Fix powerpc target to work with current qemu release. (The g3beige target switched around to more closely match hardware, so needed new kernel config. This meant it was using a serial driver broken in the kernel, so revert patch that broke it.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 24 Oct 2009 13:01:39 -0500 |
parents | 733f42839bfb |
children | eda31d43d89f |
files | sources/patches/linux-revertppcserial.patch sources/targets/powerpc/miniconfig-linux |
diffstat | 2 files changed, 565 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/patches/linux-revertppcserial.patch Sat Oct 24 13:01:39 2009 -0500 @@ -0,0 +1,561 @@ +Revert commit f751928e0ddf54ea4fe5546f35e99efc5b5d9938 which breaks +CONFIG_SERIAL_PMACZILOG irq handling, and thus the PPC serial console panics +as soon as init launches. + +See: + http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-October/076727.html + http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-October/077059.html + +diff -ru linux/drivers/serial/jsm/jsm_tty.c linux2/drivers/serial/jsm/jsm_tty.c +--- linux/drivers/serial/jsm/jsm_tty.c 2009-01-02 12:19:42.000000000 -0600 ++++ linux2/drivers/serial/jsm/jsm_tty.c 2009-10-21 18:03:31.000000000 -0500 +@@ -272,7 +272,7 @@ + jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); + + bd = channel->ch_bd; +- ts = port->info->port.tty->termios; ++ ts = channel->uart_port.info->port.tty->termios; + + channel->ch_flags &= ~(CH_STOPI); + +diff -ru linux/drivers/serial/serial_core.c linux2/drivers/serial/serial_core.c +--- linux/drivers/serial/serial_core.c 2009-01-02 12:19:42.000000000 -0600 ++++ linux2/drivers/serial/serial_core.c 2009-10-21 18:03:31.000000000 -0500 +@@ -50,7 +50,7 @@ + + #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) + +-#define uart_users(state) ((state)->count + (state)->info.port.blocked_open) ++#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->port.blocked_open : 0)) + + #ifdef CONFIG_SERIAL_CORE_CONSOLE + #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) +@@ -94,7 +94,7 @@ + struct uart_state *state = tty->driver_data; + struct uart_port *port = state->port; + +- if (!uart_circ_empty(&state->info.xmit) && state->info.xmit.buf && ++ if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf && + !tty->stopped && !tty->hw_stopped) + port->ops->start_tx(port); + } +@@ -113,7 +113,7 @@ + static void uart_tasklet_action(unsigned long data) + { + struct uart_state *state = (struct uart_state *)data; +- tty_wakeup(state->info.port.tty); ++ tty_wakeup(state->info->port.tty); + } + + static inline void +@@ -139,7 +139,7 @@ + */ + static int uart_startup(struct uart_state *state, int init_hw) + { +- struct uart_info *info = &state->info; ++ struct uart_info *info = state->info; + struct uart_port *port = state->port; + unsigned long page; + int retval = 0; +@@ -212,15 +212,14 @@ + */ + static void uart_shutdown(struct uart_state *state) + { +- struct uart_info *info = &state->info; ++ struct uart_info *info = state->info; + struct uart_port *port = state->port; +- struct tty_struct *tty = info->port.tty; + + /* + * Set the TTY IO error marker + */ +- if (tty) +- set_bit(TTY_IO_ERROR, &tty->flags); ++ if (info->port.tty) ++ set_bit(TTY_IO_ERROR, &info->port.tty->flags); + + if (info->flags & UIF_INITIALIZED) { + info->flags &= ~UIF_INITIALIZED; +@@ -228,7 +227,7 @@ + /* + * Turn off DTR and RTS early. + */ +- if (!tty || (tty->termios->c_cflag & HUPCL)) ++ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) + uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + + /* +@@ -428,7 +427,7 @@ + static void + uart_change_speed(struct uart_state *state, struct ktermios *old_termios) + { +- struct tty_struct *tty = state->info.port.tty; ++ struct tty_struct *tty = state->info->port.tty; + struct uart_port *port = state->port; + struct ktermios *termios; + +@@ -445,14 +444,14 @@ + * Set flags based on termios cflag + */ + if (termios->c_cflag & CRTSCTS) +- state->info.flags |= UIF_CTS_FLOW; ++ state->info->flags |= UIF_CTS_FLOW; + else +- state->info.flags &= ~UIF_CTS_FLOW; ++ state->info->flags &= ~UIF_CTS_FLOW; + + if (termios->c_cflag & CLOCAL) +- state->info.flags &= ~UIF_CHECK_CD; ++ state->info->flags &= ~UIF_CHECK_CD; + else +- state->info.flags |= UIF_CHECK_CD; ++ state->info->flags |= UIF_CHECK_CD; + + port->ops->set_termios(port, termios, old_termios); + } +@@ -480,7 +479,7 @@ + { + struct uart_state *state = tty->driver_data; + +- return __uart_put_char(state->port, &state->info.xmit, ch); ++ return __uart_put_char(state->port, &state->info->xmit, ch); + } + + static void uart_flush_chars(struct tty_struct *tty) +@@ -501,13 +500,13 @@ + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ +- if (!state) { ++ if (!state || !state->info) { + WARN_ON(1); + return -EL3HLT; + } + + port = state->port; +- circ = &state->info.xmit; ++ circ = &state->info->xmit; + + if (!circ->buf) + return 0; +@@ -538,7 +537,7 @@ + int ret; + + spin_lock_irqsave(&state->port->lock, flags); +- ret = uart_circ_chars_free(&state->info.xmit); ++ ret = uart_circ_chars_free(&state->info->xmit); + spin_unlock_irqrestore(&state->port->lock, flags); + return ret; + } +@@ -550,7 +549,7 @@ + int ret; + + spin_lock_irqsave(&state->port->lock, flags); +- ret = uart_circ_chars_pending(&state->info.xmit); ++ ret = uart_circ_chars_pending(&state->info->xmit); + spin_unlock_irqrestore(&state->port->lock, flags); + return ret; + } +@@ -565,7 +564,7 @@ + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ +- if (!state) { ++ if (!state || !state->info) { + WARN_ON(1); + return; + } +@@ -574,7 +573,7 @@ + pr_debug("uart_flush_buffer(%d) called\n", tty->index); + + spin_lock_irqsave(&port->lock, flags); +- uart_circ_clear(&state->info.xmit); ++ uart_circ_clear(&state->info->xmit); + if (port->ops->flush_buffer) + port->ops->flush_buffer(port); + spin_unlock_irqrestore(&port->lock, flags); +@@ -838,15 +837,15 @@ + state->closing_wait = closing_wait; + if (new_serial.xmit_fifo_size) + port->fifosize = new_serial.xmit_fifo_size; +- if (state->info.port.tty) +- state->info.port.tty->low_latency = ++ if (state->info->port.tty) ++ state->info->port.tty->low_latency = + (port->flags & UPF_LOW_LATENCY) ? 1 : 0; + + check_and_exit: + retval = 0; + if (port->type == PORT_UNKNOWN) + goto exit; +- if (state->info.flags & UIF_INITIALIZED) { ++ if (state->info->flags & UIF_INITIALIZED) { + if (((old_flags ^ port->flags) & UPF_SPD_MASK) || + old_custom_divisor != port->custom_divisor) { + /* +@@ -859,7 +858,7 @@ + printk(KERN_NOTICE + "%s sets custom speed on %s. This " + "is deprecated.\n", current->comm, +- tty_name(state->info.port.tty, buf)); ++ tty_name(state->info->port.tty, buf)); + } + uart_change_speed(state, NULL); + } +@@ -890,8 +889,8 @@ + * interrupt happens). + */ + if (port->x_char || +- ((uart_circ_chars_pending(&state->info.xmit) > 0) && +- !state->info.port.tty->stopped && !state->info.port.tty->hw_stopped)) ++ ((uart_circ_chars_pending(&state->info->xmit) > 0) && ++ !state->info->port.tty->stopped && !state->info->port.tty->hw_stopped)) + result &= ~TIOCSER_TEMT; + + return put_user(result, value); +@@ -1018,7 +1017,7 @@ + port->ops->enable_ms(port); + spin_unlock_irq(&port->lock); + +- add_wait_queue(&state->info.delta_msr_wait, &wait); ++ add_wait_queue(&state->info->delta_msr_wait, &wait); + for (;;) { + spin_lock_irq(&port->lock); + memcpy(&cnow, &port->icount, sizeof(struct uart_icount)); +@@ -1046,7 +1045,7 @@ + } + + current->state = TASK_RUNNING; +- remove_wait_queue(&state->info.delta_msr_wait, &wait); ++ remove_wait_queue(&state->info->delta_msr_wait, &wait); + + return ret; + } +@@ -1242,7 +1241,7 @@ + */ + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) +- wake_up_interruptible(&info->port.open_wait); ++ wake_up_interruptible(&state->info->port.open_wait); + #endif + } + +@@ -1304,7 +1303,7 @@ + * At this point, we stop accepting input. To do this, we + * disable the receive line status interrupts. + */ +- if (state->info.flags & UIF_INITIALIZED) { ++ if (state->info->flags & UIF_INITIALIZED) { + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); + port->ops->stop_rx(port); +@@ -1323,9 +1322,9 @@ + tty_ldisc_flush(tty); + + tty->closing = 0; +- state->info.port.tty = NULL; ++ state->info->port.tty = NULL; + +- if (state->info.port.blocked_open) { ++ if (state->info->port.blocked_open) { + if (state->close_delay) + msleep_interruptible(state->close_delay); + } else if (!uart_console(port)) { +@@ -1335,8 +1334,8 @@ + /* + * Wake up anyone trying to open this port. + */ +- state->info.flags &= ~UIF_NORMAL_ACTIVE; +- wake_up_interruptible(&state->info.port.open_wait); ++ state->info->flags &= ~UIF_NORMAL_ACTIVE; ++ wake_up_interruptible(&state->info->port.open_wait); + + done: + mutex_unlock(&state->mutex); +@@ -1410,20 +1409,19 @@ + static void uart_hangup(struct tty_struct *tty) + { + struct uart_state *state = tty->driver_data; +- struct uart_info *info = &state->info; + + BUG_ON(!kernel_locked()); + pr_debug("uart_hangup(%d)\n", state->port->line); + + mutex_lock(&state->mutex); +- if (info->flags & UIF_NORMAL_ACTIVE) { ++ if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) { + uart_flush_buffer(tty); + uart_shutdown(state); + state->count = 0; +- info->flags &= ~UIF_NORMAL_ACTIVE; +- info->port.tty = NULL; +- wake_up_interruptible(&info->port.open_wait); +- wake_up_interruptible(&info->delta_msr_wait); ++ state->info->flags &= ~UIF_NORMAL_ACTIVE; ++ state->info->port.tty = NULL; ++ wake_up_interruptible(&state->info->port.open_wait); ++ wake_up_interruptible(&state->info->delta_msr_wait); + } + mutex_unlock(&state->mutex); + } +@@ -1436,7 +1434,7 @@ + */ + static void uart_update_termios(struct uart_state *state) + { +- struct tty_struct *tty = state->info.port.tty; ++ struct tty_struct *tty = state->info->port.tty; + struct uart_port *port = state->port; + + if (uart_console(port) && port->cons->cflag) { +@@ -1471,7 +1469,7 @@ + uart_block_til_ready(struct file *filp, struct uart_state *state) + { + DECLARE_WAITQUEUE(wait, current); +- struct uart_info *info = &state->info; ++ struct uart_info *info = state->info; + struct uart_port *port = state->port; + unsigned int mctrl; + +@@ -1565,6 +1563,28 @@ + ret = -ENXIO; + goto err_unlock; + } ++ ++ /* BKL: RACE HERE - LEAK */ ++ /* We should move this into the uart_state structure and kill off ++ this whole complexity */ ++ if (!state->info) { ++ state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL); ++ if (state->info) { ++ init_waitqueue_head(&state->info->port.open_wait); ++ init_waitqueue_head(&state->info->delta_msr_wait); ++ ++ /* ++ * Link the info into the other structures. ++ */ ++ state->port->info = state->info; ++ ++ tasklet_init(&state->info->tlet, uart_tasklet_action, ++ (unsigned long)state); ++ } else { ++ ret = -ENOMEM; ++ goto err_unlock; ++ } ++ } + return state; + + err_unlock: +@@ -1621,10 +1641,9 @@ + * Any failures from here onwards should not touch the count. + */ + tty->driver_data = state; +- state->port->info = &state->info; + tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0; + tty->alt_speed = 0; +- state->info.port.tty = tty; ++ state->info->port.tty = tty; + + /* + * If the port is in the middle of closing, bail out now. +@@ -1657,8 +1676,8 @@ + /* + * If this is the first open to succeed, adjust things to suit. + */ +- if (retval == 0 && !(state->info.flags & UIF_NORMAL_ACTIVE)) { +- state->info.flags |= UIF_NORMAL_ACTIVE; ++ if (retval == 0 && !(state->info->flags & UIF_NORMAL_ACTIVE)) { ++ state->info->flags |= UIF_NORMAL_ACTIVE; + + uart_update_termios(state); + } +@@ -2009,11 +2028,11 @@ + } + port->suspended = 1; + +- if (state->info.flags & UIF_INITIALIZED) { ++ if (state->info && state->info->flags & UIF_INITIALIZED) { + const struct uart_ops *ops = port->ops; + int tries; + +- state->info.flags = (state->info.flags & ~UIF_INITIALIZED) ++ state->info->flags = (state->info->flags & ~UIF_INITIALIZED) + | UIF_SUSPENDED; + + spin_lock_irq(&port->lock); +@@ -2088,15 +2107,15 @@ + /* + * If that's unset, use the tty termios setting. + */ +- if (state->info.port.tty && termios.c_cflag == 0) +- termios = *state->info.port.tty->termios; ++ if (state->info && state->info->port.tty && termios.c_cflag == 0) ++ termios = *state->info->port.tty->termios; + + uart_change_pm(state, 0); + port->ops->set_termios(port, &termios, NULL); + console_start(port->cons); + } + +- if (state->info.flags & UIF_SUSPENDED) { ++ if (state->info && state->info->flags & UIF_SUSPENDED) { + const struct uart_ops *ops = port->ops; + int ret; + +@@ -2111,7 +2130,7 @@ + ops->set_mctrl(port, port->mctrl); + ops->start_tx(port); + spin_unlock_irq(&port->lock); +- state->info.flags |= UIF_INITIALIZED; ++ state->info->flags |= UIF_INITIALIZED; + } else { + /* + * Failed to resume - maybe hardware went away? +@@ -2121,7 +2140,7 @@ + uart_shutdown(state); + } + +- state->info.flags &= ~UIF_SUSPENDED; ++ state->info->flags &= ~UIF_SUSPENDED; + } + + mutex_unlock(&state->mutex); +@@ -2364,12 +2383,8 @@ + + state->close_delay = 500; /* .5 seconds */ + state->closing_wait = 30000; /* 30 seconds */ +- mutex_init(&state->mutex); + +- tty_port_init(&state->info.port); +- init_waitqueue_head(&state->info.delta_msr_wait); +- tasklet_init(&state->info.tlet, uart_tasklet_action, +- (unsigned long)state); ++ mutex_init(&state->mutex); + } + + retval = tty_register_driver(normal); +@@ -2440,7 +2455,7 @@ + state->pm_state = -1; + + port->cons = drv->cons; +- port->info = &state->info; ++ port->info = state->info; + + /* + * If this port is a console, then the spinlock is already +@@ -2512,11 +2527,18 @@ + */ + tty_unregister_device(drv->tty_driver, port->line); + +- info = &state->info; ++ info = state->info; + if (info && info->port.tty) + tty_vhangup(info->port.tty); + + /* ++ * All users of this port should now be disconnected from ++ * this driver, and the port shut down. We should be the ++ * only thread fiddling with this port from now on. ++ */ ++ state->info = NULL; ++ ++ /* + * Free the port IO and memory resources, if any. + */ + if (port->type != PORT_UNKNOWN) +diff -ru linux/include/linux/serial_core.h linux2/include/linux/serial_core.h +--- linux/include/linux/serial_core.h 2009-01-02 12:19:42.000000000 -0600 ++++ linux2/include/linux/serial_core.h 2009-10-21 18:03:31.000000000 -0500 +@@ -316,13 +316,35 @@ + }; + + /* ++ * This is the state information which is persistent across opens. ++ * The low level driver must not to touch any elements contained ++ * within. ++ */ ++struct uart_state { ++ unsigned int close_delay; /* msec */ ++ unsigned int closing_wait; /* msec */ ++ ++#define USF_CLOSING_WAIT_INF (0) ++#define USF_CLOSING_WAIT_NONE (~0U) ++ ++ int count; ++ int pm_state; ++ struct uart_info *info; ++ struct uart_port *port; ++ ++ struct mutex mutex; ++}; ++ ++#define UART_XMIT_SIZE PAGE_SIZE ++ ++typedef unsigned int __bitwise__ uif_t; ++ ++/* + * This is the state information which is only valid when the port +- * is open; it may be cleared the core driver once the device has ++ * is open; it may be freed by the core driver once the device has + * been closed. Either the low level driver or the core can modify + * stuff here. + */ +-typedef unsigned int __bitwise__ uif_t; +- + struct uart_info { + struct tty_port port; + struct circ_buf xmit; +@@ -344,29 +366,6 @@ + wait_queue_head_t delta_msr_wait; + }; + +-/* +- * This is the state information which is persistent across opens. +- * The low level driver must not to touch any elements contained +- * within. +- */ +-struct uart_state { +- unsigned int close_delay; /* msec */ +- unsigned int closing_wait; /* msec */ +- +-#define USF_CLOSING_WAIT_INF (0) +-#define USF_CLOSING_WAIT_NONE (~0U) +- +- int count; +- int pm_state; +- struct uart_info info; +- struct uart_port *port; +- +- struct mutex mutex; +-}; +- +-#define UART_XMIT_SIZE PAGE_SIZE +- +- + /* number of characters left in xmit buffer before we ask for more */ + #define WAKEUP_CHARS 256 + +@@ -440,13 +439,8 @@ + #define uart_circ_chars_free(circ) \ + (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) + +-static inline int uart_tx_stopped(struct uart_port *port) +-{ +- struct tty_struct *tty = port->info->port.tty; +- if(tty->stopped || tty->hw_stopped) +- return 1; +- return 0; +-} ++#define uart_tx_stopped(portp) \ ++ ((portp)->info->port.tty->stopped || (portp)->info->port.tty->hw_stopped) + + /* + * The following are helper functions for the low level drivers. +@@ -457,7 +451,7 @@ + #ifdef SUPPORT_SYSRQ + if (port->sysrq) { + if (ch && time_before(jiffies, port->sysrq)) { +- handle_sysrq(ch, port->info->port.tty); ++ handle_sysrq(ch, port->info ? port->info->port.tty : NULL); + port->sysrq = 0; + return 1; + }
--- a/sources/targets/powerpc/miniconfig-linux Mon Oct 19 14:21:11 2009 -0500 +++ b/sources/targets/powerpc/miniconfig-linux Sat Oct 24 13:01:39 2009 -0500 @@ -2,17 +2,16 @@ CONFIG_EXPERIMENTAL=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_BLK_DEV_INITRD=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y +CONFIG_LBDAF=y CONFIG_PPC_PMAC=y CONFIG_PPC_OF_BOOT_TRAMPOLINE=y CONFIG_PPC601_SYNC_FIX=y CONFIG_HIGHMEM=y CONFIG_NO_HZ=y CONFIG_BINFMT_ELF=y -CONFIG_UNEVICTABLE_LRU=y CONFIG_PROC_DEVICETREE=y CONFIG_PM=y CONFIG_SECCOMP=y @@ -37,8 +36,8 @@ CONFIG_IDE=y CONFIG_IDE_GD=y CONFIG_IDE_GD_ATA=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_CMD64X=y +CONFIG_IDE_PROC_FS=y +CONFIG_IDEPCI_PCIBUS_ORDER=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_IEEE1394=y CONFIG_IEEE1394_OHCI1394=y @@ -51,7 +50,6 @@ CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y CONFIG_NETDEVICES=y -CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_NET_ETHERNET=y CONFIG_MACE=y CONFIG_BMAC=y @@ -64,22 +62,15 @@ CONFIG_8139CP=y CONFIG_8139TOO=y CONFIG_8139TOO_PIO=y -CONFIG_ATL2=y CONFIG_SERIO=y CONFIG_SERIAL_PMACZILOG=y CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_SERIAL_PMACZILOG_CONSOLE=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=8 CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_POWERMAC=y CONFIG_SSB=y CONFIG_SSB_PCIHOST=y CONFIG_SSB_PCMCIAHOST=y CONFIG_SSB_DRIVER_PCICORE=y -CONFIG_MFD_WM8400=y -CONFIG_MFD_WM8350_I2C=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_DNOTIFY=y @@ -91,3 +82,4 @@ CONFIG_SQUASHFS=y CONFIG_LIBCRC32C=y CONFIG_BOOTX_TEXT=y +CONFIG_CRYPTO_HW=y