From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH 3/7] move setup_irq() into .init.text Date: Thu, 31 Mar 2011 16:55:43 +0100 Message-ID: <4D94C01F02000078000396C1@vpn.id2.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartFDD129EF.0__=" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: "xen-devel@lists.xensource.com" List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__PartFDD129EF.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline With no modular drivers, all interrupt setup is supposed to happen during boot. Signed-off-by: Jan Beulich --- 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)]; =20 -int setup_irq_vector(unsigned int vec, struct irqaction * new) +int __init setup_irq_vector(unsigned int vec, struct irqaction * new) { int res; =20 @@ -279,7 +279,7 @@ int setup_irq_vector(unsigned int vec, s return res; } =20 -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; } =20 -static void sn_endboot(struct serial_port *port) +static void __init sn_endboot(struct serial_port *port) { struct sn_console_data *sndata =3D port->uart; =20 @@ -69,7 +69,7 @@ static void sn_poll(void *data) } =20 =20 -static void sn_init_postirq(struct serial_port *port) +static void __init sn_init_postirq(struct serial_port *port) { struct sn_console_data *sndata =3D port->uart; =20 @@ -77,9 +77,16 @@ static void sn_init_postirq(struct seria set_timer(&sndata->timer, NOW() + MILLISECS(console_data.timeout_m= s)); } =20 +static void sn_resume(struct serial_port *port) +{ + struct sn_console_data *sndata =3D port->uart; + + set_timer(&sndata->timer, NOW() + MILLISECS(console_data.timeout_ms= )); +} =20 static struct uart_driver sn_sal_console =3D { .init_postirq =3D sn_init_postirq, + .resume =3D sn_resume, .putc =3D sn_putc, .getc =3D sn_getc, .endboot =3D 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; } =20 -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); } =20 -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); } =20 -static void __devinit ns16550_init_preirq(struct serial_port *port) +static void ns16550_setup_preirq(struct ns16550 *uart) { - struct ns16550 *uart =3D port->uart; unsigned char lcr; unsigned int divisor; =20 pci_serial_early_init(uart); =20 - /* I/O ports are distinguished by their size (16 bits). */ - if ( uart->io_base >=3D 0x10000 ) - uart->remapped_io_base =3D (char *)ioremap(uart->io_base, 8); - lcr =3D (uart->data_bits - 5) | ((uart->stop_bits - 1) << 2) | = uart->parity; =20 /* No interrupts. */ @@ -264,6 +259,17 @@ static void __devinit ns16550_init_preir =20 /* 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 =3D port->uart; + + /* I/O ports are distinguished by their size (16 bits). */ + if ( uart->io_base >=3D 0x10000 ) + uart->remapped_io_base =3D (char *)ioremap(uart->io_base, 8); + + ns16550_setup_preirq(uart); =20 /* Check this really is a 16550+. Otherwise we have no FIFOs. */ if ( ((ns_read_reg(uart, IIR) & 0xc0) =3D=3D 0xc0) && @@ -271,7 +277,27 @@ static void __devinit ns16550_init_preir port->tx_fifo_size =3D 16; } =20 -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 =3D 1; + uart->intr_works =3D 0; + ns_write_reg(uart, THR, 0xff); + } + + if ( uart->irq >=3D 0 ) + set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms)); +} + +static void __init ns16550_init_postirq(struct serial_port *port) { struct ns16550 *uart =3D port->uart; int rc, bits; @@ -281,36 +307,29 @@ static void __devinit ns16550_init_posti =20 serial_async_transmit(port); =20 - if ( !uart->timer.function ) - init_timer(&uart->timer, ns16550_poll, port, 0); + init_timer(&uart->timer, ns16550_poll, port, 0); =20 /* Calculate time to fill RX FIFO and/or empty TX FIFO for polling. = */ bits =3D uart->data_bits + uart->stop_bits + !!uart->parity; uart->timeout_ms =3D max_t( unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);= =20 - if ( uart->irq =3D=3D 0 ) - set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms)); - else + if ( uart->irq > 0 ) { uart->irqaction.handler =3D ns16550_interrupt; uart->irqaction.name =3D "ns16550"; uart->irqaction.dev_id =3D port; if ( (rc =3D setup_irq(uart->irq, &uart->irqaction)) !=3D 0 ) printk("ERROR: Failed to allocate ns16550 IRQ %d\n", = uart->irq); + } =20 - /* 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); +} =20 - /* Do a timed write to make sure we are getting interrupts. */ - uart->probing =3D 1; - uart->intr_works =3D 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); } =20 #ifdef CONFIG_X86 @@ -334,6 +353,7 @@ static struct uart_driver __read_mostly=20 .init_preirq =3D ns16550_init_preirq, .init_postirq =3D ns16550_init_postirq, .endboot =3D ns16550_endboot, + .resume =3D ns16550_resume, .tx_empty =3D ns16550_tx_empty, .putc =3D ns16550_putc, .getc =3D 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); } =20 -void __devinit serial_init_preirq(void) +void __init serial_init_preirq(void) { int i; for ( i =3D 0; i < ARRAY_SIZE(com); i++ ) @@ -428,7 +428,7 @@ void __devinit serial_init_preirq(void) com[i].driver->init_preirq(&com[i]); } =20 -void __devinit serial_init_postirq(void) +void __init serial_init_postirq(void) { int i; for ( i =3D 0; i < ARRAY_SIZE(com); i++ ) @@ -455,16 +455,18 @@ int serial_irq(int idx) =20 void serial_suspend(void) { - int i, irq; + int i; for ( i =3D 0; i < ARRAY_SIZE(com); i++ ) - if ( (irq =3D serial_irq(i)) >=3D 0 ) - release_irq(irq); + if ( com[i].driver && com[i].driver->suspend ) + com[i].driver->suspend(&com[i]); } =20 void serial_resume(void) { - serial_init_preirq(); - serial_init_postirq(); + int i; + for ( i =3D 0; i < ARRAY_SIZE(com); i++ ) + if ( com[i].driver && com[i].driver->resume ) + com[i].driver->resume(&com[i]); } =20 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 =3D 1; } =20 -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 !=3D 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. */ --=__PartFDD129EF.0__= Content-Type: text/plain; name="setup_irq-init.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="setup_irq-init.patch" With no modular drivers, all interrupt setup is supposed to happen=0Aduring= boot.=0A=0ASigned-off-by: Jan Beulich =0A=0A--- = a/xen/arch/ia64/xen/irq.c=0A+++ b/xen/arch/ia64/xen/irq.c=0A@@ -266,7 = +266,7 @@ int setup_vector(unsigned int vector, st=0A /* Vectors reserved = by xen (and thus not sharable with domains). */=0A unsigned long = ia64_xen_vector[BITS_TO_LONGS(NR_IRQS)];=0A =0A-int setup_irq_vector(unsign= ed int vec, struct irqaction * new)=0A+int __init setup_irq_vector(unsigned= int vec, struct irqaction * new)=0A {=0A int res;=0A =0A@@ -279,7 = +279,7 @@ int setup_irq_vector(unsigned int vec, s=0A return res;=0A = }=0A =0A-void release_irq_vector(unsigned int vec)=0A+void __init = release_irq_vector(unsigned int vec)=0A {=0A unsigned long flags;=0A = irq_desc_t *desc;=0A--- a/xen/arch/ia64/xen/sn_console.c=0A+++ b/xen/arch/i= a64/xen/sn_console.c=0A@@ -46,7 +46,7 @@ static int sn_getc(struct = serial_port *p=0A return 1;=0A }=0A =0A-static void sn_endboot(struct= serial_port *port)=0A+static void __init sn_endboot(struct serial_port = *port)=0A {=0A struct sn_console_data *sndata =3D port->uart;=0A =0A@@ = -69,7 +69,7 @@ static void sn_poll(void *data)=0A }=0A =0A =0A-static void = sn_init_postirq(struct serial_port *port)=0A+static void __init sn_init_pos= tirq(struct serial_port *port)=0A {=0A struct sn_console_data *sndata =3D = port->uart;=0A =0A@@ -77,9 +77,16 @@ static void sn_init_postirq(struct = seria=0A set_timer(&sndata->timer, NOW() + MILLISECS(console_data.t= imeout_ms));=0A }=0A =0A+static void sn_resume(struct serial_port = *port)=0A+{=0A+ struct sn_console_data *sndata =3D port->uart;=0A+=0A+ = set_timer(&sndata->timer, NOW() + MILLISECS(console_data.timeout_ms));=0A+}= =0A =0A static struct uart_driver sn_sal_console =3D {=0A .init_posti= rq =3D sn_init_postirq,=0A+ .resume =3D sn_resume,=0A .putc =3D = sn_putc,=0A .getc =3D sn_getc,=0A .endboot =3D sn_endboot,=0A--- = a/xen/arch/x86/irq.c=0A+++ b/xen/arch/x86/irq.c=0A@@ -677,7 +677,7 @@ int = __init request_irq(unsigned int irq,=0A return retval;=0A }=0A = =0A-void release_irq(unsigned int irq)=0A+void __init release_irq(unsigned = int irq)=0A {=0A struct irq_desc *desc;=0A unsigned long flags;=0A@= @ -700,7 +700,7 @@ void release_irq(unsigned int irq)=0A xfree(acti= on);=0A }=0A =0A-int setup_irq(unsigned int irq, struct irqaction = *new)=0A+int __init setup_irq(unsigned int irq, struct irqaction *new)=0A = {=0A struct irq_desc *desc;=0A unsigned long flags;=0A--- = a/xen/drivers/char/ns16550.c=0A+++ b/xen/drivers/char/ns16550.c=0A@@ = -224,18 +224,13 @@ static void pci_serial_early_init(struct=0A = 0x4, 0x1);=0A }=0A =0A-static void __devinit ns16550_init_preirq(struct = serial_port *port)=0A+static void ns16550_setup_preirq(struct ns16550 = *uart)=0A {=0A- struct ns16550 *uart =3D port->uart;=0A unsigned = char lcr;=0A unsigned int divisor;=0A =0A pci_serial_early_init(ua= rt);=0A =0A- /* I/O ports are distinguished by their size (16 bits). = */=0A- if ( uart->io_base >=3D 0x10000 )=0A- uart->remapped_io_ba= se =3D (char *)ioremap(uart->io_base, 8);=0A-=0A lcr =3D (uart->data_bi= ts - 5) | ((uart->stop_bits - 1) << 2) | uart->parity;=0A =0A /* No = interrupts. */=0A@@ -264,6 +259,17 @@ static void __devinit ns16550_init_pr= eir=0A =0A /* Enable and clear the FIFOs. Set a large trigger = threshold. */=0A ns_write_reg(uart, FCR, FCR_ENABLE | FCR_CLRX | = FCR_CLTX | FCR_TRG14);=0A+}=0A+=0A+static void __init ns16550_init_preirq(s= truct serial_port *port)=0A+{=0A+ struct ns16550 *uart =3D port->uart;= =0A+=0A+ /* I/O ports are distinguished by their size (16 bits). */=0A+ = if ( uart->io_base >=3D 0x10000 )=0A+ uart->remapped_io_base =3D = (char *)ioremap(uart->io_base, 8);=0A+=0A+ ns16550_setup_preirq(uart);= =0A =0A /* Check this really is a 16550+. Otherwise we have no FIFOs. = */=0A if ( ((ns_read_reg(uart, IIR) & 0xc0) =3D=3D 0xc0) &&=0A@@ = -271,7 +277,27 @@ static void __devinit ns16550_init_preir=0A = port->tx_fifo_size =3D 16;=0A }=0A =0A-static void __devinit ns16550_init_p= ostirq(struct serial_port *port)=0A+static void ns16550_setup_postirq(struc= t ns16550 *uart)=0A+{=0A+ if ( uart->irq > 0 )=0A+ {=0A+ /* = Master interrupt enable; also keep DTR/RTS asserted. */=0A+ = ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);=0A+=0A+ /* = Enable receive and transmit interrupts. */=0A+ ns_write_reg(uart, = IER, IER_ERDAI | IER_ETHREI);=0A+=0A+ /* Do a timed write to make = sure we are getting interrupts. */=0A+ uart->probing =3D 1;=0A+ = uart->intr_works =3D 0;=0A+ ns_write_reg(uart, THR, 0xff);=0A+ = }=0A+=0A+ if ( uart->irq >=3D 0 )=0A+ set_timer(&uart->timer, = NOW() + MILLISECS(uart->timeout_ms));=0A+}=0A+=0A+static void __init = ns16550_init_postirq(struct serial_port *port)=0A {=0A struct ns16550 = *uart =3D port->uart;=0A int rc, bits;=0A@@ -281,36 +307,29 @@ static = void __devinit ns16550_init_posti=0A =0A serial_async_transmit(port);= =0A =0A- if ( !uart->timer.function )=0A- init_timer(&uart->timer= , ns16550_poll, port, 0);=0A+ init_timer(&uart->timer, ns16550_poll, = port, 0);=0A =0A /* Calculate time to fill RX FIFO and/or empty TX = FIFO for polling. */=0A bits =3D uart->data_bits + uart->stop_bits + = !!uart->parity;=0A uart->timeout_ms =3D max_t(=0A unsigned = int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);=0A =0A- if ( = uart->irq =3D=3D 0 )=0A- set_timer(&uart->timer, NOW() + MILLISECS(u= art->timeout_ms));=0A- else=0A+ if ( uart->irq > 0 )=0A {=0A = uart->irqaction.handler =3D ns16550_interrupt;=0A uart->irqacti= on.name =3D "ns16550";=0A uart->irqaction.dev_id =3D port;=0A = if ( (rc =3D setup_irq(uart->irq, &uart->irqaction)) !=3D 0 )=0A = printk("ERROR: Failed to allocate ns16550 IRQ %d\n", uart->irq);= =0A+ }=0A =0A- /* Master interrupt enable; also keep DTR/RTS = asserted. */=0A- ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | = MCR_RTS);=0A-=0A- /* Enable receive and transmit interrupts. */=0A- = ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);=0A+ ns16550_setu= p_postirq(uart);=0A+}=0A =0A- /* Do a timed write to make sure we = are getting interrupts. */=0A- uart->probing =3D 1;=0A- = uart->intr_works =3D 0;=0A- ns_write_reg(uart, THR, 0xff);=0A- = set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));=0A- = }=0A+static void ns16550_resume(struct serial_port *port)=0A+{=0A+ = ns16550_setup_preirq(port->uart);=0A+ ns16550_setup_postirq(port->uart);= =0A }=0A =0A #ifdef CONFIG_X86=0A@@ -334,6 +353,7 @@ static struct = uart_driver __read_mostly =0A .init_preirq =3D ns16550_init_preirq,=0A= .init_postirq =3D ns16550_init_postirq,=0A .endboot =3D = ns16550_endboot,=0A+ .resume =3D ns16550_resume,=0A .tx_empty = =3D ns16550_tx_empty,=0A .putc =3D ns16550_putc,=0A = .getc =3D ns16550_getc,=0A--- a/xen/drivers/char/serial.c=0A+++ = b/xen/drivers/char/serial.c=0A@@ -420,7 +420,7 @@ void serial_end_log_every= thing(int handl=0A spin_unlock_irqrestore(&port->tx_lock, flags);=0A = }=0A =0A-void __devinit serial_init_preirq(void)=0A+void __init serial_init= _preirq(void)=0A {=0A int i;=0A for ( i =3D 0; i < ARRAY_SIZE(com);= i++ )=0A@@ -428,7 +428,7 @@ void __devinit serial_init_preirq(void)=0A = com[i].driver->init_preirq(&com[i]);=0A }=0A =0A-void __devinit = serial_init_postirq(void)=0A+void __init serial_init_postirq(void)=0A {=0A = int i;=0A for ( i =3D 0; i < ARRAY_SIZE(com); i++ )=0A@@ -455,16 = +455,18 @@ int serial_irq(int idx)=0A =0A void serial_suspend(void)=0A = {=0A- int i, irq;=0A+ int i;=0A for ( i =3D 0; i < ARRAY_SIZE(com= ); i++ )=0A- if ( (irq =3D serial_irq(i)) >=3D 0 )=0A- = release_irq(irq);=0A+ if ( com[i].driver && com[i].driver->suspend = )=0A+ com[i].driver->suspend(&com[i]);=0A }=0A =0A void = serial_resume(void)=0A {=0A- serial_init_preirq();=0A- serial_init_po= stirq();=0A+ int i;=0A+ for ( i =3D 0; i < ARRAY_SIZE(com); i++ = )=0A+ if ( com[i].driver && com[i].driver->resume )=0A+ = com[i].driver->resume(&com[i]);=0A }=0A =0A void __init serial_register_uar= t(int idx, struct uart_driver *driver,=0A@@ -478,7 +480,7 @@ void __init = serial_register_uart(int idx=0A com[idx].tx_fifo_size =3D 1;=0A }=0A = =0A-void serial_async_transmit(struct serial_port *port)=0A+void __init = serial_async_transmit(struct serial_port *port)=0A {=0A BUG_ON(!port->d= river->tx_empty);=0A if ( port->txbuf !=3D NULL )=0A--- a/xen/include/x= en/serial.h=0A+++ b/xen/include/xen/serial.h=0A@@ -51,6 +51,9 @@ struct = uart_driver {=0A void (*init_postirq)(struct serial_port *);=0A /* = Hook to clean up after Xen bootstrap (before domain 0 runs). */=0A = void (*endboot)(struct serial_port *);=0A+ /* Driver suspend/resume. = */=0A+ void (*suspend)(struct serial_port *);=0A+ void (*resume)(stru= ct serial_port *);=0A /* Transmit FIFO ready to receive up to = @tx_fifo_size characters? */=0A int (*tx_empty)(struct serial_port = *);=0A /* Put a character onto the serial line. */=0A --=__PartFDD129EF.0__= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --=__PartFDD129EF.0__=--