[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/7] move setup_irq() into .init.text



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. */


Attachment: setup_irq-init.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.