Enable wakeup from serial ports, make it run-time configurable over sysfs, e.g.,
echo enabled > /sys/devices/platform/serial8250.0/tty/ttyS0/power/wakeup Requires # CONFIG_SYSFS_DEPRECATED is not set Signed-off-by: Guennadi Liakhovetski <[EMAIL PROTECTED]> --- (I still find it strange having to put a formal patch description above and its discussion below, anyway) On Mon, 13 Aug 2007, Greg KH wrote: > So, the serial8250 device is the "bridge" for the 4 different serial > ports in my machine. You have the tty:ttyS? symlinks in that directory > as you have CONFIG_SYSFS_DEPRECATED still enabled, but the directory > structure should all still be the same for you. > > So, if you want to put things into the tty device's directory, you can, > they will just show up in the proper place, under > /sys/devices/platform/serial8250/tty/ttyS0 for the first serial port. > > Does that make sense? I think it does... Following this, and a suggestion from Scott to switch wakeup-enable on and off at run-time over sysfs, here's another attempt... Well, easy to see I'm out in the wild here in this area (pm/sysfs/tty), so, this might well be way off... Please, comment. Thanks Guennadi diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0b3ec38..5118914 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -130,6 +130,7 @@ struct uart_8250_port { unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ unsigned char lsr_break_flag; + char suspended; /* * We provide a per-port pm hook. @@ -2673,6 +2674,14 @@ static int __devexit serial8250_remove(struct platform_device *dev) return 0; } +static int serial8250_match_port(struct device *dev, void *data) +{ + struct uart_port *port = data; + dev_t devt = MKDEV(serial8250_reg.major, serial8250_reg.minor) + port->line; + + return dev->devt == devt; /* Actually, only one tty per port */ +} + static int serial8250_suspend(struct platform_device *dev, pm_message_t state) { int i; @@ -2680,8 +2689,16 @@ static int serial8250_suspend(struct platform_device *dev, pm_message_t state) for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; - if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) - uart_suspend_port(&serial8250_reg, &up->port); + if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) { + struct device *tty_dev = device_find_child(up->port.dev, &up->port, + serial8250_match_port); + if (device_may_wakeup(tty_dev)) + enable_irq_wake(up->port.irq); + else { + uart_suspend_port(&serial8250_reg, &up->port); + up->suspended = 1; + } + } } return 0; @@ -2694,8 +2711,13 @@ static int serial8250_resume(struct platform_device *dev) for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; - if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) - serial8250_resume_port(i); + if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) { + if (up->suspended) { + serial8250_resume_port(i); + up->suspended = 0; + } else + disable_irq_wake(up->port.irq); + } } return 0; diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 9c57486..716fbe2 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -2266,6 +2266,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) { struct uart_state *state; int ret = 0; + struct device *tty_dev; BUG_ON(in_interrupt()); @@ -2301,7 +2302,13 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) * Register the port whether it's detected or not. This allows * setserial to be used to alter this ports parameters. */ - tty_register_device(drv->tty_driver, port->line, port->dev); + tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev); + if (likely(!IS_ERR(tty_dev))) { + device_can_wakeup(tty_dev) = 1; + device_set_wakeup_enable(tty_dev, 0); + } else + printk(KERN_ERR "Cannot register tty device on line %d\n", + port->line); /* * If this driver supports console, and it hasn't been _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev