With no modular drivers, all interrupt setup is supposed to happen
during boot.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
--- a/xen/arch/ia64/xen/irq.c
+++ b/xen/arch/ia64/xen/irq.c
@@ -266,7 +266,7 @@ int setup_vector(unsigned int vector, st
/* Vectors reserved by xen (and thus not sharable with domains). */
unsigned long ia64_xen_vector[BITS_TO_LONGS(NR_IRQS)];
-int setup_irq_vector(unsigned int vec, struct irqaction * new)
+int __init setup_irq_vector(unsigned int vec, struct irqaction * new)
{
int res;
@@ -279,7 +279,7 @@ int setup_irq_vector(unsigned int vec, s
return res;
}
-void release_irq_vector(unsigned int vec)
+void __init release_irq_vector(unsigned int vec)
{
unsigned long flags;
irq_desc_t *desc;
--- a/xen/arch/ia64/xen/sn_console.c
+++ b/xen/arch/ia64/xen/sn_console.c
@@ -46,7 +46,7 @@ static int sn_getc(struct serial_port *p
return 1;
}
-static void sn_endboot(struct serial_port *port)
+static void __init sn_endboot(struct serial_port *port)
{
struct sn_console_data *sndata = port->uart;
@@ -69,7 +69,7 @@ static void sn_poll(void *data)
}
-static void sn_init_postirq(struct serial_port *port)
+static void __init sn_init_postirq(struct serial_port *port)
{
struct sn_console_data *sndata = port->uart;
@@ -77,9 +77,16 @@ static void sn_init_postirq(struct seria
set_timer(&sndata->timer, NOW() + MILLISECS(console_data.timeout_ms));
}
+static void sn_resume(struct serial_port *port)
+{
+ struct sn_console_data *sndata = port->uart;
+
+ set_timer(&sndata->timer, NOW() + MILLISECS(console_data.timeout_ms));
+}
static struct uart_driver sn_sal_console = {
.init_postirq = sn_init_postirq,
+ .resume = sn_resume,
.putc = sn_putc,
.getc = sn_getc,
.endboot = sn_endboot,
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -677,7 +677,7 @@ int __init request_irq(unsigned int irq,
return retval;
}
-void release_irq(unsigned int irq)
+void __init release_irq(unsigned int irq)
{
struct irq_desc *desc;
unsigned long flags;
@@ -700,7 +700,7 @@ void release_irq(unsigned int irq)
xfree(action);
}
-int setup_irq(unsigned int irq, struct irqaction *new)
+int __init setup_irq(unsigned int irq, struct irqaction *new)
{
struct irq_desc *desc;
unsigned long flags;
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -224,18 +224,13 @@ static void pci_serial_early_init(struct
0x4, 0x1);
}
-static void __devinit ns16550_init_preirq(struct serial_port *port)
+static void ns16550_setup_preirq(struct ns16550 *uart)
{
- struct ns16550 *uart = port->uart;
unsigned char lcr;
unsigned int divisor;
pci_serial_early_init(uart);
- /* I/O ports are distinguished by their size (16 bits). */
- if ( uart->io_base >= 0x10000 )
- uart->remapped_io_base = (char *)ioremap(uart->io_base, 8);
-
lcr = (uart->data_bits - 5) | ((uart->stop_bits - 1) << 2) | uart->parity;
/* No interrupts. */
@@ -264,6 +259,17 @@ static void __devinit ns16550_init_preir
/* Enable and clear the FIFOs. Set a large trigger threshold. */
ns_write_reg(uart, FCR, FCR_ENABLE | FCR_CLRX | FCR_CLTX | FCR_TRG14);
+}
+
+static void __init ns16550_init_preirq(struct serial_port *port)
+{
+ struct ns16550 *uart = port->uart;
+
+ /* I/O ports are distinguished by their size (16 bits). */
+ if ( uart->io_base >= 0x10000 )
+ uart->remapped_io_base = (char *)ioremap(uart->io_base, 8);
+
+ ns16550_setup_preirq(uart);
/* Check this really is a 16550+. Otherwise we have no FIFOs. */
if ( ((ns_read_reg(uart, IIR) & 0xc0) == 0xc0) &&
@@ -271,7 +277,27 @@ static void __devinit ns16550_init_preir
port->tx_fifo_size = 16;
}
-static void __devinit ns16550_init_postirq(struct serial_port *port)
+static void ns16550_setup_postirq(struct ns16550 *uart)
+{
+ if ( uart->irq > 0 )
+ {
+ /* Master interrupt enable; also keep DTR/RTS asserted. */
+ ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
+
+ /* Enable receive and transmit interrupts. */
+ ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+
+ /* Do a timed write to make sure we are getting interrupts. */
+ uart->probing = 1;
+ uart->intr_works = 0;
+ ns_write_reg(uart, THR, 0xff);
+ }
+
+ if ( uart->irq >= 0 )
+ set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+}
+
+static void __init ns16550_init_postirq(struct serial_port *port)
{
struct ns16550 *uart = port->uart;
int rc, bits;
@@ -281,36 +307,29 @@ static void __devinit ns16550_init_posti
serial_async_transmit(port);
- if ( !uart->timer.function )
- init_timer(&uart->timer, ns16550_poll, port, 0);
+ init_timer(&uart->timer, ns16550_poll, port, 0);
/* Calculate time to fill RX FIFO and/or empty TX FIFO for polling. */
bits = uart->data_bits + uart->stop_bits + !!uart->parity;
uart->timeout_ms = max_t(
unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
- if ( uart->irq == 0 )
- set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
- else
+ if ( uart->irq > 0 )
{
uart->irqaction.handler = ns16550_interrupt;
uart->irqaction.name = "ns16550";
uart->irqaction.dev_id = port;
if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
printk("ERROR: Failed to allocate ns16550 IRQ %d\n", uart->irq);
+ }
- /* Master interrupt enable; also keep DTR/RTS asserted. */
- ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
-
- /* Enable receive and transmit interrupts. */
- ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+ ns16550_setup_postirq(uart);
+}
- /* Do a timed write to make sure we are getting interrupts. */
- uart->probing = 1;
- uart->intr_works = 0;
- ns_write_reg(uart, THR, 0xff);
- set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
- }
+static void ns16550_resume(struct serial_port *port)
+{
+ ns16550_setup_preirq(port->uart);
+ ns16550_setup_postirq(port->uart);
}
#ifdef CONFIG_X86
@@ -334,6 +353,7 @@ static struct uart_driver __read_mostly
.init_preirq = ns16550_init_preirq,
.init_postirq = ns16550_init_postirq,
.endboot = ns16550_endboot,
+ .resume = ns16550_resume,
.tx_empty = ns16550_tx_empty,
.putc = ns16550_putc,
.getc = ns16550_getc,
--- a/xen/drivers/char/serial.c
+++ b/xen/drivers/char/serial.c
@@ -420,7 +420,7 @@ void serial_end_log_everything(int handl
spin_unlock_irqrestore(&port->tx_lock, flags);
}
-void __devinit serial_init_preirq(void)
+void __init serial_init_preirq(void)
{
int i;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
@@ -428,7 +428,7 @@ void __devinit serial_init_preirq(void)
com[i].driver->init_preirq(&com[i]);
}
-void __devinit serial_init_postirq(void)
+void __init serial_init_postirq(void)
{
int i;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
@@ -455,16 +455,18 @@ int serial_irq(int idx)
void serial_suspend(void)
{
- int i, irq;
+ int i;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
- if ( (irq = serial_irq(i)) >= 0 )
- release_irq(irq);
+ if ( com[i].driver && com[i].driver->suspend )
+ com[i].driver->suspend(&com[i]);
}
void serial_resume(void)
{
- serial_init_preirq();
- serial_init_postirq();
+ int i;
+ for ( i = 0; i < ARRAY_SIZE(com); i++ )
+ if ( com[i].driver && com[i].driver->resume )
+ com[i].driver->resume(&com[i]);
}
void __init serial_register_uart(int idx, struct uart_driver *driver,
@@ -478,7 +480,7 @@ void __init serial_register_uart(int idx
com[idx].tx_fifo_size = 1;
}
-void serial_async_transmit(struct serial_port *port)
+void __init serial_async_transmit(struct serial_port *port)
{
BUG_ON(!port->driver->tx_empty);
if ( port->txbuf != NULL )
--- a/xen/include/xen/serial.h
+++ b/xen/include/xen/serial.h
@@ -51,6 +51,9 @@ struct uart_driver {
void (*init_postirq)(struct serial_port *);
/* Hook to clean up after Xen bootstrap (before domain 0 runs). */
void (*endboot)(struct serial_port *);
+ /* Driver suspend/resume. */
+ void (*suspend)(struct serial_port *);
+ void (*resume)(struct serial_port *);
/* Transmit FIFO ready to receive up to @tx_fifo_size characters? */
int (*tx_empty)(struct serial_port *);
/* Put a character onto the serial line. */
setup_irq-init.patch
Description: Text document
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|