143 lines
4.0 KiB
Diff
143 lines
4.0 KiB
Diff
|
# HG changeset patch
|
||
|
# User Jan Beulich <jbeulich@suse.com>
|
||
|
# Date 1347371512 -7200
|
||
|
# Node ID e1380b5311ccee14eb47d7badb75339933d42249
|
||
|
# Parent 0d0c55a1975db9c6cac2e9259b5ebea7a7bdbaec
|
||
|
serial: avoid fully initializing unused consoles
|
||
|
|
||
|
Defer calling the drivers' post-IRQ initialization functions (generally
|
||
|
doing allocation of transmit buffers) until it is known that the
|
||
|
respective console is actually going to be used.
|
||
|
|
||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||
|
Acked-by: Keir Fraser <keir@xen.org>
|
||
|
|
||
|
--- a/xen/drivers/char/ehci-dbgp.c
|
||
|
+++ b/xen/drivers/char/ehci-dbgp.c
|
||
|
@@ -1391,7 +1391,8 @@ static int ehci_dbgp_check_release(struc
|
||
|
printk(XENLOG_INFO "Releasing EHCI debug port at %02x:%02x.%u\n",
|
||
|
dbgp->bus, dbgp->slot, dbgp->func);
|
||
|
|
||
|
- kill_timer(&dbgp->timer);
|
||
|
+ if ( dbgp->timer.function )
|
||
|
+ kill_timer(&dbgp->timer);
|
||
|
dbgp->ehci_debug = NULL;
|
||
|
|
||
|
ctrl = readl(&ehci_debug->control);
|
||
|
--- a/xen/drivers/char/serial.c
|
||
|
+++ b/xen/drivers/char/serial.c
|
||
|
@@ -29,6 +29,8 @@ static struct serial_port com[SERHND_IDX
|
||
|
}
|
||
|
};
|
||
|
|
||
|
+static bool_t __read_mostly post_irq;
|
||
|
+
|
||
|
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
|
||
|
{
|
||
|
char c;
|
||
|
@@ -263,14 +265,12 @@ char serial_getc(int handle)
|
||
|
|
||
|
int __init serial_parse_handle(char *conf)
|
||
|
{
|
||
|
- int handle;
|
||
|
+ int handle, flags = 0;
|
||
|
|
||
|
if ( !strncmp(conf, "dbgp", 4) && (!conf[4] || conf[4] == ',') )
|
||
|
{
|
||
|
- if ( !com[SERHND_DBGP].driver )
|
||
|
- goto fail;
|
||
|
-
|
||
|
- return SERHND_DBGP | SERHND_COOKED;
|
||
|
+ handle = SERHND_DBGP;
|
||
|
+ goto common;
|
||
|
}
|
||
|
|
||
|
if ( strncmp(conf, "com", 3) )
|
||
|
@@ -288,17 +288,25 @@ int __init serial_parse_handle(char *con
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
- if ( !com[handle].driver )
|
||
|
- goto fail;
|
||
|
-
|
||
|
if ( conf[4] == 'H' )
|
||
|
- handle |= SERHND_HI;
|
||
|
+ flags |= SERHND_HI;
|
||
|
else if ( conf[4] == 'L' )
|
||
|
- handle |= SERHND_LO;
|
||
|
+ flags |= SERHND_LO;
|
||
|
|
||
|
- handle |= SERHND_COOKED;
|
||
|
+ common:
|
||
|
+ if ( !com[handle].driver )
|
||
|
+ goto fail;
|
||
|
+
|
||
|
+ if ( !post_irq )
|
||
|
+ com[handle].state = serial_parsed;
|
||
|
+ else if ( com[handle].state != serial_initialized )
|
||
|
+ {
|
||
|
+ if ( com[handle].driver->init_postirq )
|
||
|
+ com[handle].driver->init_postirq(&com[handle]);
|
||
|
+ com[handle].state = serial_initialized;
|
||
|
+ }
|
||
|
|
||
|
- return handle;
|
||
|
+ return handle | flags | SERHND_COOKED;
|
||
|
|
||
|
fail:
|
||
|
return -1;
|
||
|
@@ -450,8 +458,13 @@ void __init serial_init_postirq(void)
|
||
|
{
|
||
|
int i;
|
||
|
for ( i = 0; i < ARRAY_SIZE(com); i++ )
|
||
|
- if ( com[i].driver && com[i].driver->init_postirq )
|
||
|
- com[i].driver->init_postirq(&com[i]);
|
||
|
+ if ( com[i].state == serial_parsed )
|
||
|
+ {
|
||
|
+ if ( com[i].driver->init_postirq )
|
||
|
+ com[i].driver->init_postirq(&com[i]);
|
||
|
+ com[i].state = serial_initialized;
|
||
|
+ }
|
||
|
+ post_irq = 1;
|
||
|
}
|
||
|
|
||
|
void __init serial_endboot(void)
|
||
|
@@ -475,7 +488,7 @@ void serial_suspend(void)
|
||
|
{
|
||
|
int i;
|
||
|
for ( i = 0; i < ARRAY_SIZE(com); i++ )
|
||
|
- if ( com[i].driver && com[i].driver->suspend )
|
||
|
+ if ( com[i].state == serial_initialized && com[i].driver->suspend )
|
||
|
com[i].driver->suspend(&com[i]);
|
||
|
}
|
||
|
|
||
|
@@ -483,7 +496,7 @@ void serial_resume(void)
|
||
|
{
|
||
|
int i;
|
||
|
for ( i = 0; i < ARRAY_SIZE(com); i++ )
|
||
|
- if ( com[i].driver && com[i].driver->resume )
|
||
|
+ if ( com[i].state == serial_initialized && com[i].driver->resume )
|
||
|
com[i].driver->resume(&com[i]);
|
||
|
}
|
||
|
|
||
|
--- a/xen/include/xen/serial.h
|
||
|
+++ b/xen/include/xen/serial.h
|
||
|
@@ -25,10 +25,17 @@ extern unsigned int serial_txbufsz;
|
||
|
|
||
|
struct uart_driver;
|
||
|
|
||
|
+enum serial_port_state {
|
||
|
+ serial_unused,
|
||
|
+ serial_parsed,
|
||
|
+ serial_initialized
|
||
|
+};
|
||
|
+
|
||
|
struct serial_port {
|
||
|
/* Uart-driver parameters. */
|
||
|
struct uart_driver *driver;
|
||
|
void *uart;
|
||
|
+ enum serial_port_state state;
|
||
|
/* Number of characters the port can hold for transmit. */
|
||
|
int tx_fifo_size;
|
||
|
/* Transmit data buffer (interrupt-driven uart). */
|