diff options
author | Paul Mundt <lethal@linux-sh.org> | 2012-03-28 13:53:10 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2012-03-28 13:53:10 +0900 |
commit | 18af30e259c25a64ad69bb749c661564bc886275 (patch) | |
tree | 996c89594fd20f25fcc15b5843625d99473f6982 /arch/ia64 | |
parent | 691c01c3f0b3252308162de90edcd02f7ca1733c (diff) | |
parent | 6658a6991cef75719a21441aa0b7f8d6821534ee (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into sh-latest
Diffstat (limited to 'arch/ia64')
26 files changed, 235 insertions, 686 deletions
diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c index bf6d9d8c802f..0216e28300fa 100644 --- a/arch/ia64/hp/sim/boot/fw-emu.c +++ b/arch/ia64/hp/sim/boot/fw-emu.c @@ -160,28 +160,19 @@ sal_emulator (long index, unsigned long in1, unsigned long in2, */ status = 0; if (index == SAL_FREQ_BASE) { - switch (in1) { - case SAL_FREQ_BASE_PLATFORM: + if (in1 == SAL_FREQ_BASE_PLATFORM) r9 = 200000000; - break; - - case SAL_FREQ_BASE_INTERVAL_TIMER: + else if (in1 == SAL_FREQ_BASE_INTERVAL_TIMER) { /* * Is this supposed to be the cr.itc frequency * or something platform specific? The SAL * doc ain't exactly clear on this... */ r9 = 700000000; - break; - - case SAL_FREQ_BASE_REALTIME_CLOCK: + } else if (in1 == SAL_FREQ_BASE_REALTIME_CLOCK) r9 = 1; - break; - - default: + else status = -1; - break; - } } else if (index == SAL_SET_VECTORS) { ; } else if (index == SAL_GET_STATE_INFO) { diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index 4bd9a63260ee..0aa70ebda49d 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c @@ -10,6 +10,8 @@ #include <linux/sched.h> #include <linux/irq.h> +#include "hpsim_ssc.h" + static unsigned int hpsim_irq_startup(struct irq_data *data) { @@ -37,15 +39,37 @@ static struct irq_chip irq_type_hp_sim = { .irq_set_affinity = hpsim_set_affinity_noop, }; +static void hpsim_irq_set_chip(int irq) +{ + struct irq_chip *chip = irq_get_chip(irq); + + if (chip == &no_irq_chip) + irq_set_chip(irq, &irq_type_hp_sim); +} + +static void hpsim_connect_irq(int intr, int irq) +{ + ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); +} + +int hpsim_get_irq(int intr) +{ + int irq = assign_irq_vector(AUTO_ASSIGN); + + if (irq >= 0) { + hpsim_irq_set_chip(irq); + irq_set_handler(irq, handle_simple_irq); + hpsim_connect_irq(intr, irq); + } + + return irq; +} + void __init hpsim_irq_init (void) { int i; - for_each_active_irq(i) { - struct irq_chip *chip = irq_get_chip(i); - - if (chip == &no_irq_chip) - irq_set_chip(i, &irq_type_hp_sim); - } + for_each_active_irq(i) + hpsim_irq_set_chip(i); } diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c index f629e903ebc7..664a5402a695 100644 --- a/arch/ia64/hp/sim/hpsim_setup.c +++ b/arch/ia64/hp/sim/hpsim_setup.c @@ -26,12 +26,6 @@ #include "hpsim_ssc.h" void -ia64_ssc_connect_irq (long intr, long irq) -{ - ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); -} - -void ia64_ctl_trace (long on) { ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE); diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index 47afcc61f6e5..a63218e1f6c9 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -129,17 +129,6 @@ netdev_probe(char *name, unsigned char *ether) static inline int -netdev_connect(int irq) -{ - /* XXX Fix me - * this does not support multiple cards - * also no return value - */ - ia64_ssc_connect_irq(NETWORK_INTR, irq); - return 0; -} - -static inline int netdev_attach(int fd, int irq, unsigned int ipaddr) { /* this puts the host interface in the right mode (start interrupting) */ @@ -193,7 +182,7 @@ simeth_probe1(void) unsigned char mac_addr[ETH_ALEN]; struct simeth_local *local; struct net_device *dev; - int fd, i, err, rc; + int fd, err, rc; /* * XXX Fix me @@ -226,22 +215,16 @@ simeth_probe1(void) return err; } - if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) - panic("%s: out of interrupt vectors!\n", __func__); - dev->irq = rc; - /* * attach the interrupt in the simulator, this does enable interrupts * until a netdev_attach() is called */ - netdev_connect(dev->irq); + if ((rc = hpsim_get_irq(NETWORK_INTR)) < 0) + panic("%s: out of interrupt vectors!\n", __func__); + dev->irq = rc; - printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr", - dev->name, simeth_device, local->simfd); - for(i = 0; i < ETH_ALEN; i++) { - printk(" %2.2x", dev->dev_addr[i]); - } - printk(", IRQ %d\n", dev->irq); + printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr=%pm, IRQ %d\n", + dev->name, simeth_device, local->simfd, dev->dev_addr, dev->irq); return 0; } diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index bff0824cf8a4..c34785dca92b 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -4,16 +4,11 @@ * This driver is mostly used for bringup purposes and will go away. * It has a strong dependency on the system console. All outputs * are rerouted to the same facility as the one used by printk which, in our - * case means sys_sim.c console (goes via the simulator). The code hereafter - * is completely leveraged from the serial.c driver. + * case means sys_sim.c console (goes via the simulator). * * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co * Stephane Eranian <eranian@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com> - * - * 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close(). - * 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c. - * 07/30/02 D. Mosberger Replace sti()/cli() with explicit spinlocks & local irq masking */ #include <linux/init.h> @@ -27,15 +22,17 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/capability.h> +#include <linux/circ_buf.h> #include <linux/console.h> +#include <linux/irq.h> #include <linux/module.h> #include <linux/serial.h> -#include <linux/serialP.h> #include <linux/sysrq.h> +#include <linux/uaccess.h> + +#include <asm/hpsim.h> -#include <asm/irq.h> -#include <asm/hw_irq.h> -#include <asm/uaccess.h> +#include "hpsim_ssc.h" #undef SIMSERIAL_DEBUG /* define this to get some debug information */ @@ -43,118 +40,44 @@ #define NR_PORTS 1 /* only one port for now */ -#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED) - -#define SSC_GETCHAR 21 - -extern long ia64_ssc (long, long, long, long, int); -extern void ia64_ssc_connect_irq (long intr, long irq); - -static char *serial_name = "SimSerial driver"; -static char *serial_version = "0.6"; - -/* - * This has been extracted from asm/serial.h. We need one eventually but - * I don't know exactly what we're going to put in it so just fake one - * for now. - */ -#define BASE_BAUD ( 1843200 / 16 ) - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - -/* - * Most of the values here are meaningless to this particular driver. - * However some values must be preserved for the code (leveraged from serial.c - * to work correctly). - * port must not be 0 - * type must not be UNKNOWN - * So I picked arbitrary (guess from where?) values instead - */ -static struct serial_state rs_table[NR_PORTS]={ - /* UART CLK PORT IRQ FLAGS */ - { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 } /* ttyS0 */ +struct serial_state { + struct tty_port port; + struct circ_buf xmit; + int irq; + int x_char; }; -/* - * Just for the fun of it ! - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, - { "8250", 1, 0 }, - { "16450", 1, 0 }, - { "16550", 1, 0 }, - { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, - { "cirrus", 1, 0 }, - { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, - { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | - UART_STARTECH }, - { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, - { NULL, 0} -}; +static struct serial_state rs_table[NR_PORTS]; struct tty_driver *hp_simserial_driver; -static struct async_struct *IRQ_ports[NR_IRQS]; - static struct console *console; -static unsigned char *tmp_buf; - -extern struct console *console_drivers; /* from kernel/printk.c */ - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ -#ifdef SIMSERIAL_DEBUG - printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", - tty->stopped, tty->hw_stopped, tty->flow_stopped); -#endif - -} - -static void rs_start(struct tty_struct *tty) -{ -#ifdef SIMSERIAL_DEBUG - printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", - tty->stopped, tty->hw_stopped, tty->flow_stopped); -#endif -} - -static void receive_chars(struct tty_struct *tty) +static void receive_chars(struct tty_struct *tty) { unsigned char ch; static unsigned char seen_esc = 0; while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) { - if ( ch == 27 && seen_esc == 0 ) { + if (ch == 27 && seen_esc == 0) { seen_esc = 1; continue; - } else { - if ( seen_esc==1 && ch == 'O' ) { - seen_esc = 2; - continue; - } else if ( seen_esc == 2 ) { - if ( ch == 'P' ) /* F1 */ - show_state(); + } else if (seen_esc == 1 && ch == 'O') { + seen_esc = 2; + continue; + } else if (seen_esc == 2) { + if (ch == 'P') /* F1 */ + show_state(); #ifdef CONFIG_MAGIC_SYSRQ - if ( ch == 'S' ) { /* F4 */ - do - ch = ia64_ssc(0, 0, 0, 0, - SSC_GETCHAR); - while (!ch); - handle_sysrq(ch); - } -#endif - seen_esc = 0; - continue; + if (ch == 'S') { /* F4 */ + do { + ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR); + } while (!ch); + handle_sysrq(ch); } +#endif + seen_esc = 0; + continue; } seen_esc = 0; @@ -169,22 +92,19 @@ static void receive_chars(struct tty_struct *tty) */ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) { - struct async_struct * info; + struct serial_state *info = dev_id; + struct tty_struct *tty = tty_port_tty_get(&info->port); - /* - * I don't know exactly why they don't use the dev_id opaque data - * pointer instead of this extra lookup table - */ - info = IRQ_ports[irq]; - if (!info || !info->tty) { - printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info); + if (!tty) { + printk(KERN_INFO "%s: tty=0 problem\n", __func__); return IRQ_NONE; } /* * pretty simple in our case, because we only get interrupts * on inbound traffic */ - receive_chars(info->tty); + receive_chars(tty); + tty_kref_put(tty); return IRQ_HANDLED; } @@ -194,17 +114,12 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) * ------------------------------------------------------------------- */ -static void do_softint(struct work_struct *private_) -{ - printk(KERN_ERR "simserial: do_softint called\n"); -} - static int rs_put_char(struct tty_struct *tty, unsigned char ch) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; unsigned long flags; - if (!tty || !info->xmit.buf) + if (!info->xmit.buf) return 0; local_irq_save(flags); @@ -218,12 +133,12 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch) return 1; } -static void transmit_chars(struct async_struct *info, int *intr_done) +static void transmit_chars(struct tty_struct *tty, struct serial_state *info, + int *intr_done) { int count; unsigned long flags; - local_irq_save(flags); if (info->x_char) { @@ -231,16 +146,16 @@ static void transmit_chars(struct async_struct *info, int *intr_done) console->write(console, &c, 1); - info->state->icount.tx++; info->x_char = 0; goto out; } - if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { + if (info->xmit.head == info->xmit.tail || tty->stopped || + tty->hw_stopped) { #ifdef SIMSERIAL_DEBUG printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", - info->xmit.head, info->xmit.tail, info->tty->stopped); + info->xmit.head, info->xmit.tail, tty->stopped); #endif goto out; } @@ -272,24 +187,24 @@ out: static void rs_flush_chars(struct tty_struct *tty) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; - if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped || - !info->xmit.buf) + if (info->xmit.head == info->xmit.tail || tty->stopped || + tty->hw_stopped || !info->xmit.buf) return; - transmit_chars(info, NULL); + transmit_chars(tty, info, NULL); } - static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) { + struct serial_state *info = tty->driver_data; int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; - if (!tty || !info->xmit.buf || !tmp_buf) return 0; + if (!info->xmit.buf) + return 0; local_irq_save(flags); while (1) { @@ -310,30 +225,30 @@ static int rs_write(struct tty_struct * tty, /* * Hey, we transmit directly from here in our case */ - if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) - && !tty->stopped && !tty->hw_stopped) { - transmit_chars(info, NULL); - } + if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && + !tty->stopped && !tty->hw_stopped) + transmit_chars(tty, info, NULL); + return ret; } static int rs_write_room(struct tty_struct *tty) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); } static int rs_chars_in_buffer(struct tty_struct *tty) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); } static void rs_flush_buffer(struct tty_struct *tty) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; unsigned long flags; local_irq_save(flags); @@ -349,7 +264,7 @@ static void rs_flush_buffer(struct tty_struct *tty) */ static void rs_send_xchar(struct tty_struct *tty, char ch) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; info->x_char = ch; if (ch) { @@ -357,7 +272,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) * I guess we could call console->write() directly but * let's do that for now. */ - transmit_chars(info, NULL); + transmit_chars(tty, info, NULL); } } @@ -371,14 +286,15 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) */ static void rs_throttle(struct tty_struct * tty) { - if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); printk(KERN_INFO "simrs_throttle called\n"); } static void rs_unthrottle(struct tty_struct * tty) { - struct async_struct *info = (struct async_struct *)tty->driver_data; + struct serial_state *info = tty->driver_data; if (I_IXOFF(tty)) { if (info->x_char) @@ -389,7 +305,6 @@ static void rs_unthrottle(struct tty_struct * tty) printk(KERN_INFO "simrs_unthrottle called\n"); } - static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && @@ -400,48 +315,21 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) } switch (cmd) { - case TIOCGSERIAL: - printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n"); - return 0; - case TIOCSSERIAL: - printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n"); - return 0; - case TIOCSERCONFIG: - printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n"); - return -EINVAL; - - case TIOCSERGETLSR: /* Get line status register */ - printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n"); - return -EINVAL; - - case TIOCSERGSTRUCT: - printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n"); -#if 0 - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; -#endif - return 0; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n"); - return 0; - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; + case TIOCGSERIAL: + case TIOCSSERIAL: + case TIOCSERGSTRUCT: + case TIOCMIWAIT: + return 0; + case TIOCSERCONFIG: + case TIOCSERGETLSR: /* Get line status register */ + return -EINVAL; + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + } + return -ENOIOCTLCMD; } #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) @@ -452,220 +340,50 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { tty->hw_stopped = 0; - rs_start(tty); } } /* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. */ -static void shutdown(struct async_struct * info) +static void shutdown(struct tty_port *port) { - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) return; - - state = info->state; - -#ifdef SIMSERIAL_DEBUG - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif + struct serial_state *info = container_of(port, struct serial_state, + port); + unsigned long flags; local_irq_save(flags); - { - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - - /* - * Free the IRQ, if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, NULL); - retval = request_irq(state->irq, rs_interrupt_single, - IRQ_T(info), "serial", NULL); - - if (retval) - printk(KERN_ERR "serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, NULL); - } - - if (info->xmit.buf) { - free_page((unsigned long) info->xmit.buf); - info->xmit.buf = NULL; - } - - if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->irq) + free_irq(info->irq, info); - info->flags &= ~ASYNC_INITIALIZED; + if (info->xmit.buf) { + free_page((unsigned long) info->xmit.buf); + info->xmit.buf = NULL; } local_irq_restore(flags); } -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ static void rs_close(struct tty_struct *tty, struct file * filp) { - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info ) return; - - state = info->state; - - local_irq_save(flags); - if (tty_hung_up_p(filp)) { -#ifdef SIMSERIAL_DEBUG - printk("rs_close: hung_up\n"); -#endif - local_irq_restore(flags); - return; - } -#ifdef SIMSERIAL_DEBUG - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - local_irq_restore(flags); - return; - } - info->flags |= ASYNC_CLOSING; - local_irq_restore(flags); + struct serial_state *info = tty->driver_data; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - shutdown(info); - rs_flush_buffer(tty); - tty_ldisc_flush(tty); - info->event = 0; - info->tty = NULL; - if (info->blocked_open) { - if (info->close_delay) - schedule_timeout_interruptible(info->close_delay); - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); + tty_port_close(&info->port, tty, filp); } -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ -} - - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ static void rs_hangup(struct tty_struct *tty) { - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - -#ifdef SIMSERIAL_DEBUG - printk("rs_hangup: called\n"); -#endif - - state = info->state; + struct serial_state *info = tty->driver_data; rs_flush_buffer(tty); - if (info->flags & ASYNC_CLOSING) - return; - shutdown(info); - - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = NULL; - wake_up_interruptible(&info->open_wait); + tty_port_hangup(&info->port); } - -static int get_async_struct(int line, struct async_struct **ret_info) +static int activate(struct tty_port *port, struct tty_struct *tty) { - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - INIT_WORK(&info->work, do_softint); - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -static int -startup(struct async_struct *info) -{ - unsigned long flags; - int retval=0; - irq_handler_t handler; - struct serial_state *state= info->state; - unsigned long page; + struct serial_state *state = container_of(port, struct serial_state, + port); + unsigned long flags, page; + int retval = 0; page = get_zeroed_page(GFP_KERNEL); if (!page) @@ -673,86 +391,31 @@ startup(struct async_struct *info) local_irq_save(flags); - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (!state->port || !state->type) { - if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit.buf) + if (state->xmit.buf) free_page(page); else - info->xmit.buf = (unsigned char *) page; - -#ifdef SIMSERIAL_DEBUG - printk("startup: ttys%d (irq %d)...", info->line, state->irq); -#endif + state->xmit.buf = (unsigned char *) page; - /* - * Allocate the IRQ if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - retval = -EBUSY; - goto errout; - } else - handler = rs_interrupt_single; - - retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } + if (state->irq) { + retval = request_irq(state->irq, rs_interrupt_single, 0, + "simserial", state); + if (retval) goto errout; - } } - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = NULL; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - - if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); - - info->xmit.head = info->xmit.tail = 0; - -#if 0 - /* - * Set up serial timers... - */ - timer_table[RS_TIMER].expires = jiffies + 2*HZ/100; - timer_active |= 1 << RS_TIMER; -#endif + state->xmit.head = state->xmit.tail = 0; /* * Set up the tty->alt_speed kludge */ - if (info->tty) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - } - - info->flags |= ASYNC_INITIALIZED; - local_irq_restore(flags); - return 0; + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + tty->alt_speed = 57600; + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + tty->alt_speed = 115200; + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + tty->alt_speed = 230400; + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + tty->alt_speed = 460800; errout: local_irq_restore(flags); @@ -768,56 +431,11 @@ errout: */ static int rs_open(struct tty_struct *tty, struct file * filp) { - struct async_struct *info; - int retval, line; - unsigned long page; + struct serial_state *info = rs_table + tty->index; + struct tty_port *port = &info->port; - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) - return -ENODEV; - retval = get_async_struct(line, &info); - if (retval) - return retval; tty->driver_data = info; - info->tty = tty; - -#ifdef SIMSERIAL_DEBUG - printk("rs_open %s, count = %d\n", tty->name, info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - return retval; - } + tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; /* * figure out which console to use (should be one already) @@ -828,30 +446,21 @@ static int rs_open(struct tty_struct *tty, struct file * filp) console = console->next; } -#ifdef SIMSERIAL_DEBUG - printk("rs_open ttys%d successful\n", info->line); -#endif - return 0; + return tty_port_open(port, tty, filp); } /* * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct serial_state *state) -{ - seq_printf(m, "%d: uart:%s port:%lX irq:%d\n", - state->line, uart_config[state->type].name, - state->port, state->irq); -} - static int rs_proc_show(struct seq_file *m, void *v) { int i; - seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version); + seq_printf(m, "simserinfo:1.0\n"); for (i = 0; i < NR_PORTS; i++) - line_info(m, &rs_table[i]); + seq_printf(m, "%d: uart:16550 port:3F8 irq:%d\n", + i, rs_table[i].irq); return 0; } @@ -868,25 +477,6 @@ static const struct file_operations rs_proc_fops = { .release = single_release, }; -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static inline void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s with", serial_name, serial_version); - printk(KERN_INFO " no serial options enabled\n"); -} - static const struct tty_operations hp_ops = { .open = rs_open, .close = rs_close, @@ -901,34 +491,31 @@ static const struct tty_operations hp_ops = { .unthrottle = rs_unthrottle, .send_xchar = rs_send_xchar, .set_termios = rs_set_termios, - .stop = rs_stop, - .start = rs_start, .hangup = rs_hangup, - .wait_until_sent = rs_wait_until_sent, .proc_fops = &rs_proc_fops, }; -/* - * The serial driver boot-time initialization code! - */ -static int __init -simrs_init (void) +static const struct tty_port_operations hp_port_ops = { + .activate = activate, + .shutdown = shutdown, +}; + +static int __init simrs_init(void) { - int i, rc; - struct serial_state *state; + struct serial_state *state; + int retval; if (!ia64_platform_is("hpsim")) return -ENODEV; - hp_simserial_driver = alloc_tty_driver(1); + hp_simserial_driver = alloc_tty_driver(NR_PORTS); if (!hp_simserial_driver) return -ENOMEM; - show_serial_version(); + printk(KERN_INFO "SimSerial driver with no serial options enabled\n"); /* Initialize the tty_driver structure */ - hp_simserial_driver->owner = THIS_MODULE; hp_simserial_driver->driver_name = "simserial"; hp_simserial_driver->name = "ttyS"; hp_simserial_driver->major = TTY_MAJOR; @@ -941,31 +528,33 @@ simrs_init (void) hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(hp_simserial_driver, &hp_ops); - /* - * Let's have a little bit of fun ! - */ - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + state = rs_table; + tty_port_init(&state->port); + state->port.ops = &hp_port_ops; + state->port.close_delay = 0; /* XXX really 0? */ - if (state->type == PORT_UNKNOWN) continue; + retval = hpsim_get_irq(KEYBOARD_INTR); + if (retval < 0) { + printk(KERN_ERR "%s: out of interrupt vectors!\n", + __func__); + goto err_free_tty; + } - if (!state->irq) { - if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) - panic("%s: out of interrupt vectors!\n", - __func__); - state->irq = rc; - ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); - } + state->irq = retval; - printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n", - state->line, - state->port, state->irq, - uart_config[state->type].name); - } + /* the port is imaginary */ + printk(KERN_INFO "ttyS0 at 0x03f8 (irq = %d) is a 16550\n", state->irq); - if (tty_register_driver(hp_simserial_driver)) - panic("Couldn't register simserial driver\n"); + retval = tty_register_driver(hp_simserial_driver); + if (retval) { + printk(KERN_ERR "Couldn't register simserial driver\n"); + goto err_free_tty; + } return 0; +err_free_tty: + put_tty_driver(hp_simserial_driver); + return retval; } #ifndef MODULE diff --git a/arch/ia64/include/asm/hpsim.h b/arch/ia64/include/asm/hpsim.h index 892ab198a9da..0fe50225daa4 100644 --- a/arch/ia64/include/asm/hpsim.h +++ b/arch/ia64/include/asm/hpsim.h @@ -10,7 +10,7 @@ int simcons_register(void); struct tty_driver; extern struct tty_driver *hp_simserial_driver; -void ia64_ssc_connect_irq(long intr, long irq); +extern int hpsim_get_irq(int intr); void ia64_ctl_trace(long on); #endif diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index 32551d304cd7..b149b88ea795 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h @@ -281,9 +281,9 @@ paravirt_init_missing_ticks_accounting(int cpu) pv_time_ops.init_missing_ticks_accounting(cpu); } -struct jump_label_key; -extern struct jump_label_key paravirt_steal_enabled; -extern struct jump_label_key paravirt_steal_rq_enabled; +struct static_key; +extern struct static_key paravirt_steal_enabled; +extern struct static_key paravirt_steal_rq_enabled; static inline int paravirt_do_steal_accounting(unsigned long *new_itm) diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 279b38ae74aa..b22e5f5fa593 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -108,12 +108,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) return (pci_domain_nr(bus) != 0); } -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, struct pci_bus_region *region); - static inline struct resource * pcibios_select_root(struct pci_dev *pdev, struct resource *res) { diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h index 4b03664e3fb5..41fc28a4a18a 100644 --- a/arch/ia64/include/asm/socket.h +++ b/arch/ia64/include/asm/socket.h @@ -73,5 +73,9 @@ #define SO_WIFI_STATUS 41 #define SCM_WIFI_STATUS SO_WIFI_STATUS +#define SO_PEEK_OFF 42 + +/* Instruct lower device to use last 4-bytes of skb data as FCS */ +#define SO_NOFCS 43 #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h index fbb519828aa1..09d5f7fd9db1 100644 --- a/arch/ia64/include/asm/xen/interface.h +++ b/arch/ia64/include/asm/xen/interface.h @@ -77,6 +77,7 @@ DEFINE_GUEST_HANDLE(int); DEFINE_GUEST_HANDLE(long); DEFINE_GUEST_HANDLE(void); DEFINE_GUEST_HANDLE(uint64_t); +DEFINE_GUEST_HANDLE(uint32_t); typedef unsigned long xen_pfn_t; DEFINE_GUEST_HANDLE(xen_pfn_t); diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 5207035dc061..2d801bfe16ac 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -349,11 +349,11 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, iosapic_override_isa_irq(p->source_irq, p->global_irq, ((p->inti_flags & ACPI_MADT_POLARITY_MASK) == - ACPI_MADT_POLARITY_ACTIVE_HIGH) ? - IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + ACPI_MADT_POLARITY_ACTIVE_LOW) ? + IOSAPIC_POL_LOW : IOSAPIC_POL_HIGH, ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) == - ACPI_MADT_TRIGGER_EDGE) ? - IOSAPIC_EDGE : IOSAPIC_LEVEL); + ACPI_MADT_TRIGGER_LEVEL) ? + IOSAPIC_LEVEL : IOSAPIC_EDGE); return 0; } diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c index 4eed35814994..070e8effa175 100644 --- a/arch/ia64/kernel/machine_kexec.c +++ b/arch/ia64/kernel/machine_kexec.c @@ -157,7 +157,7 @@ void arch_crash_save_vmcoreinfo(void) #endif #ifdef CONFIG_PGTABLE_3 VMCOREINFO_CONFIG(PGTABLE_3); -#elif CONFIG_PGTABLE_4 +#elif defined(CONFIG_PGTABLE_4) VMCOREINFO_CONFIG(PGTABLE_4); #endif } diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 84fb405eee87..8192009cb924 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1447,6 +1447,8 @@ out: /* Get the CMC error record and log it */ ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC); + local_irq_disable(); + return IRQ_HANDLED; } diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index 100868216c55..1b22f6de2932 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c @@ -634,8 +634,8 @@ struct pv_irq_ops pv_irq_ops = { * pv_time_ops * time operations */ -struct jump_label_key paravirt_steal_enabled; -struct jump_label_key paravirt_steal_rq_enabled; +struct static_key paravirt_steal_enabled; +struct static_key paravirt_steal_rq_enabled; static int ia64_native_do_steal_accounting(unsigned long *new_itm) diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 6d33c5cc94f0..9dc52b63fc87 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -330,9 +330,7 @@ cpu_idle (void) normal_xtp(); #endif } - preempt_enable_no_resched(); - schedule(); - preempt_disable(); + schedule_preempt_disabled(); check_pgt_cache(); if (cpu_is_offline(cpu)) play_dead(); diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index f82f5d4b65fd..d1ce3200147c 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -320,7 +320,8 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) * Ignore these tiny memory ranges */ if (!((window->resource.flags & IORESOURCE_MEM) && (window->resource.end - window->resource.start < 16))) - pci_add_resource(&info->resources, &window->resource); + pci_add_resource_offset(&info->resources, &window->resource, + window->offset); return AE_OK; } @@ -395,54 +396,6 @@ out1: return NULL; } -void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res) -{ - struct pci_controller *controller = PCI_CONTROLLER(dev); - unsigned long offset = 0; - int i; - - for (i = 0; i < controller->windows; i++) { - struct pci_window *window = &controller->window[i]; - if (!(window->resource.flags & res->flags)) - continue; - if (window->resource.start > res->start) - continue; - if (window->resource.end < res->end) - continue; - offset = window->offset; - break; - } - - region->start = res->start - offset; - region->end = res->end - offset; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, struct pci_bus_region *region) -{ - struct pci_controller *controller = PCI_CONTROLLER(dev); - unsigned long offset = 0; - int i; - - for (i = 0; i < controller->windows; i++) { - struct pci_window *window = &controller->window[i]; - if (!(window->resource.flags & res->flags)) - continue; - if (window->resource.start - window->offset > region->start) - continue; - if (window->resource.end - window->offset < region->end) - continue; - offset = window->offset; - break; - } - - res->start = region->start + offset; - res->end = region->end + offset; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - static int __devinit is_valid_resource(struct pci_dev *dev, int idx) { unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; @@ -464,15 +417,11 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) static void __devinit pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) { - struct pci_bus_region region; int i; for (i = start; i < limit; i++) { if (!dev->resource[i].flags) continue; - region.start = dev->resource[i].start; - region.end = dev->resource[i].end; - pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); if ((is_valid_resource(dev, i))) pci_claim_resource(dev, i); } diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c index 08b0d9bb62ec..f925dec2da92 100644 --- a/arch/ia64/sn/kernel/huberror.c +++ b/arch/ia64/sn/kernel/huberror.c @@ -192,6 +192,7 @@ void hub_error_init(struct hubdev_info *hubdev_info) hubdev_info); return; } + irq_set_handler(SGI_II_ERROR, handle_level_irq); sn_set_err_irq_affinity(SGI_II_ERROR); } @@ -213,6 +214,7 @@ void ice_error_init(struct hubdev_info *hubdev_info) hubdev_info); return; } + irq_set_handler(SGI_TIO_ERROR, handle_level_irq); sn_set_err_irq_affinity(SGI_TIO_ERROR); } diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 4433dd019d3c..fbb5f2f87eed 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -7,6 +7,7 @@ */ #include <linux/bootmem.h> +#include <linux/export.h> #include <linux/slab.h> #include <asm/sn/types.h> #include <asm/sn/addrs.h> diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 0a36f082eaf1..238e2c511d94 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -297,7 +297,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) s64 status = 0; struct pci_controller *controller; struct pcibus_bussoft *prom_bussoft_ptr; - + LIST_HEAD(resources); + int i; status = sal_get_pcibus_info((u64) segment, (u64) busnum, (u64) ia64_tpa(&prom_bussoft_ptr)); @@ -315,7 +316,15 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) */ controller->platform_data = prom_bussoft_ptr; - bus = pci_scan_bus(busnum, &pci_root_ops, controller); + sn_legacy_pci_window_fixup(controller, + prom_bussoft_ptr->bs_legacy_io, + prom_bussoft_ptr->bs_legacy_mem); + for (i = 0; i < controller->windows; i++) + pci_add_resource_offset(&resources, + &controller->window[i].resource, + controller->window[i].offset); + bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, + &resources); if (bus == NULL) goto error_return; /* error, or bus already scanned */ @@ -348,9 +357,6 @@ sn_bus_fixup(struct pci_bus *bus) return; } sn_common_bus_fixup(bus, prom_bussoft_ptr); - sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), - prom_bussoft_ptr->bs_legacy_io, - prom_bussoft_ptr->bs_legacy_mem); } list_for_each_entry(pci_dev, &bus->devices, bus_list) { sn_io_slot_fixup(pci_dev); diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index dfac09ab027a..62cf4dde6a04 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -352,6 +352,8 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) spin_lock(&sn_irq_info_lock); list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); reserve_irq_vector(sn_irq_info->irq_irq); + if (sn_irq_info->irq_int_bit != -1) + irq_set_handler(sn_irq_info->irq_irq, handle_level_irq); spin_unlock(&sn_irq_info_lock); register_intr_pda(sn_irq_info); diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 2de41d44266e..4554f68b7865 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -25,6 +25,7 @@ #include <linux/fs.h> #include <linux/slab.h> +#include <linux/export.h> #include <linux/vmalloc.h> #include <linux/seq_file.h> #include <linux/miscdevice.h> diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index c1bd1cfda327..2f406f509d44 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -191,6 +191,7 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, struct hubdev_info *hubdev, int bt) { struct cx_dev *cx_dev; + int r; cx_dev = kzalloc(sizeof(struct cx_dev), GFP_KERNEL); DBG("cx_dev= 0x%p\n", cx_dev); @@ -207,7 +208,11 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, cx_dev->dev.bus = &tiocx_bus_type; cx_dev->dev.release = tiocx_bus_release; dev_set_name(&cx_dev->dev, "%d", cx_dev->cx_id.nasid); - device_register(&cx_dev->dev); + r = device_register(&cx_dev->dev); + if (r) { + kfree(cx_dev); + return r; + } get_device(&cx_dev->dev); device_create_file(&cx_dev->dev, &dev_attr_cxdev_control); diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 8886a0bc4a11..8dbbef4a4f47 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -146,6 +146,7 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont printk(KERN_WARNING "pcibr cannot allocate interrupt for error handler\n"); } + irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq); sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); /* diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index e77c477245fd..a70b11fd57d6 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -649,6 +649,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont __func__, SGI_TIOCA_ERROR, (int)tioca_common->ca_common.bs_persist_busnum); + irq_set_handler(SGI_TIOCA_ERROR, handle_level_irq); sn_set_err_irq_affinity(SGI_TIOCA_ERROR); /* Setup locality information */ diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 27faba035f3a..46d3df4b03a1 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -1037,6 +1037,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont tioce_common->ce_pcibus.bs_persist_segment, tioce_common->ce_pcibus.bs_persist_busnum); + irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq); sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); return tioce_common; } diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c index b279e142c633..3bb12230721f 100644 --- a/arch/ia64/xen/irq_xen.c +++ b/arch/ia64/xen/irq_xen.c @@ -58,7 +58,7 @@ xen_free_irq_vector(int vector) irq_op.vector = vector; if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op)) - printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n", + printk(KERN_WARNING "%s: xen_free_irq_vector fail vector=%d\n", __func__, vector); } |