Natsemi UART owner test request (was Re: [PATCH] wake up from a serial port)

2007-09-14 Thread Guennadi Liakhovetski
On Wed, 12 Sep 2007, Andrew Morton wrote:

> On Wed, 12 Sep 2007 20:50:10 +0200 (CEST)
> Guennadi Liakhovetski <[EMAIL PROTECTED]> wrote:
> 
> > 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]>
> > 
> > ---

[snip]

> > Also would be nice to test with a Natsemi UART, that can wake up 
> > the system, if such systems exist.
> 
> It would help if you could provide simple-to-follow steps which a tester
> should follow to perform this testing.

Ok, for anyone owning a system with a Natsemi UART and capable to suspend 
and resume it (you do not have to be able to resume it from the UART), 
would be great to have the patch below tested. For this you just have to 
apply the patch below, issue the above "echo" command to one of your 
Natsemi port, suspend and resume your system, and verify that your Natsemi 
port still works. If you are actually capable of waking up the system from 
that port, would be nice to test that as well.

Thanks
Guennadi

> > diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
> > index 9c57486..8a3d6ea 100644
> > --- a/drivers/serial/serial_core.c
> > +++ b/drivers/serial/serial_core.c
> > @@ -1934,9 +1934,24 @@ static void uart_change_pm(struct uart_state *state, 
> > int pm_state)
> > }
> >  }
> >  
> > +struct uart_match {
> > +   struct uart_port *port;
> > +   struct uart_driver *driver;
> > +};
> > +
> > +static int serial_match_port(struct device *dev, void *data)
> > +{
> > +   struct uart_match *match = data;
> > +   dev_t devt = MKDEV(match->driver->major, match->driver->minor) + 
> > match->port->line;
> > +
> > +   return dev->devt == devt; /* Actually, only one tty per port */
> > +}
> > +
> >  int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
> >  {
> > struct uart_state *state = drv->state + port->line;
> > +   struct device *tty_dev;
> > +   struct uart_match match = {port, drv};
> >  
> > mutex_lock(>mutex);
> >  
> > @@ -1947,6 +1962,15 @@ int uart_suspend_port(struct uart_driver *drv, 
> > struct uart_port *port)
> > }
> >  #endif
> >  
> > +   tty_dev = device_find_child(port->dev, , serial_match_port);
> > +   if (device_may_wakeup(tty_dev)) {
> > +   enable_irq_wake(port->irq);
> > +   put_device(tty_dev);
> > +   mutex_unlock(>mutex);
> > +   return 0;
> > +   }
> > +   port->suspended = 1;
> > +
> > if (state->info && state->info->flags & UIF_INITIALIZED) {
> > const struct uart_ops *ops = port->ops;
> >  
> > @@ -1995,6 +2019,13 @@ int uart_resume_port(struct uart_driver *drv, struct 
> > uart_port *port)
> > }
> >  #endif
> >  
> > +   if (!port->suspended) {
> > +   disable_irq_wake(port->irq);
> > +   mutex_unlock(>mutex);
> > +   return 0;
> > +   }
> > +   port->suspended = 0;
> > +
> > uart_change_pm(state, 0);
> >  
> > /*
> > @@ -2266,6 +2297,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 +2333,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
> > diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> > index 773d8d8..60dedc0 100644
> > --- a/include/linux/serial_core.h
> > +++ b/include/linux/serial_core.h
> > @@ -291,7 +291,8 @@ struct uart_port {
> > unsigned long   mapbase;/* for ioremap */
> > struct device   *dev;   /* parent device */
> > unsigned char   hub6;   /* this should be in 
> > the 8250 driver */
> > -   unsigned char   unused[3];
> > +   unsigned char   suspended;
> > +   unsigned char   unused[2];
> > void*private_data;  /* generic platform 
> > data pointer */
> >  };
> >  
> 

---
Guennadi Liakhovetski
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  

Natsemi UART owner test request (was Re: [PATCH] wake up from a serial port)

2007-09-14 Thread Guennadi Liakhovetski
On Wed, 12 Sep 2007, Andrew Morton wrote:

 On Wed, 12 Sep 2007 20:50:10 +0200 (CEST)
 Guennadi Liakhovetski [EMAIL PROTECTED] wrote:
 
  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]
  
  ---

[snip]

  Also would be nice to test with a Natsemi UART, that can wake up 
  the system, if such systems exist.
 
 It would help if you could provide simple-to-follow steps which a tester
 should follow to perform this testing.

Ok, for anyone owning a system with a Natsemi UART and capable to suspend 
and resume it (you do not have to be able to resume it from the UART), 
would be great to have the patch below tested. For this you just have to 
apply the patch below, issue the above echo command to one of your 
Natsemi port, suspend and resume your system, and verify that your Natsemi 
port still works. If you are actually capable of waking up the system from 
that port, would be nice to test that as well.

Thanks
Guennadi

  diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
  index 9c57486..8a3d6ea 100644
  --- a/drivers/serial/serial_core.c
  +++ b/drivers/serial/serial_core.c
  @@ -1934,9 +1934,24 @@ static void uart_change_pm(struct uart_state *state, 
  int pm_state)
  }
   }
   
  +struct uart_match {
  +   struct uart_port *port;
  +   struct uart_driver *driver;
  +};
  +
  +static int serial_match_port(struct device *dev, void *data)
  +{
  +   struct uart_match *match = data;
  +   dev_t devt = MKDEV(match-driver-major, match-driver-minor) + 
  match-port-line;
  +
  +   return dev-devt == devt; /* Actually, only one tty per port */
  +}
  +
   int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
   {
  struct uart_state *state = drv-state + port-line;
  +   struct device *tty_dev;
  +   struct uart_match match = {port, drv};
   
  mutex_lock(state-mutex);
   
  @@ -1947,6 +1962,15 @@ int uart_suspend_port(struct uart_driver *drv, 
  struct uart_port *port)
  }
   #endif
   
  +   tty_dev = device_find_child(port-dev, match, serial_match_port);
  +   if (device_may_wakeup(tty_dev)) {
  +   enable_irq_wake(port-irq);
  +   put_device(tty_dev);
  +   mutex_unlock(state-mutex);
  +   return 0;
  +   }
  +   port-suspended = 1;
  +
  if (state-info  state-info-flags  UIF_INITIALIZED) {
  const struct uart_ops *ops = port-ops;
   
  @@ -1995,6 +2019,13 @@ int uart_resume_port(struct uart_driver *drv, struct 
  uart_port *port)
  }
   #endif
   
  +   if (!port-suspended) {
  +   disable_irq_wake(port-irq);
  +   mutex_unlock(state-mutex);
  +   return 0;
  +   }
  +   port-suspended = 0;
  +
  uart_change_pm(state, 0);
   
  /*
  @@ -2266,6 +2297,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 +2333,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
  diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
  index 773d8d8..60dedc0 100644
  --- a/include/linux/serial_core.h
  +++ b/include/linux/serial_core.h
  @@ -291,7 +291,8 @@ struct uart_port {
  unsigned long   mapbase;/* for ioremap */
  struct device   *dev;   /* parent device */
  unsigned char   hub6;   /* this should be in 
  the 8250 driver */
  -   unsigned char   unused[3];
  +   unsigned char   suspended;
  +   unsigned char   unused[2];
  void*private_data;  /* generic platform 
  data pointer */
   };
   
 

---
Guennadi Liakhovetski
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] wake up from a serial port

2007-09-13 Thread Greg KH
On Wed, Sep 12, 2007 at 03:36:10PM -0700, Andrew Morton wrote:
> On Wed, 12 Sep 2007 20:50:10 +0200 (CEST)
> Guennadi Liakhovetski <[EMAIL PROTECTED]> wrote:
> 
> > 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]>
> > 
> > ---
> > 
> > Following suggestions from Alan and Russell moved the may_wake_up checks 
> > to serial_core.c. This time actually tested - it does even work. Could 
> > someone, please, verify, that put_device after device_find_child is 
> > correct?
> 
> Seems right to me, from reading device_find_child() and its associated
> documentation.

Yes, that is correct.

thanks,

greg k-h
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] wake up from a serial port

2007-09-13 Thread Greg KH
On Wed, Sep 12, 2007 at 03:36:10PM -0700, Andrew Morton wrote:
 On Wed, 12 Sep 2007 20:50:10 +0200 (CEST)
 Guennadi Liakhovetski [EMAIL PROTECTED] wrote:
 
  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]
  
  ---
  
  Following suggestions from Alan and Russell moved the may_wake_up checks 
  to serial_core.c. This time actually tested - it does even work. Could 
  someone, please, verify, that put_device after device_find_child is 
  correct?
 
 Seems right to me, from reading device_find_child() and its associated
 documentation.

Yes, that is correct.

thanks,

greg k-h
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] wake up from a serial port

2007-09-12 Thread Andrew Morton
On Wed, 12 Sep 2007 20:50:10 +0200 (CEST)
Guennadi Liakhovetski <[EMAIL PROTECTED]> wrote:

> 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]>
> 
> ---
> 
> Following suggestions from Alan and Russell moved the may_wake_up checks 
> to serial_core.c. This time actually tested - it does even work. Could 
> someone, please, verify, that put_device after device_find_child is 
> correct?

Seems right to me, from reading device_find_child() and its associated
documentation.

> Also would be nice to test with a Natsemi UART, that can wake up 
> the system, if such systems exist.
>

It would help if you could provide simple-to-follow steps which a tester
should follow to perform this testing.

 > 
> diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
> index 9c57486..8a3d6ea 100644
> --- a/drivers/serial/serial_core.c
> +++ b/drivers/serial/serial_core.c
> @@ -1934,9 +1934,24 @@ static void uart_change_pm(struct uart_state *state, 
> int pm_state)
>   }
>  }
>  
> +struct uart_match {
> + struct uart_port *port;
> + struct uart_driver *driver;
> +};
> +
> +static int serial_match_port(struct device *dev, void *data)
> +{
> + struct uart_match *match = data;
> + dev_t devt = MKDEV(match->driver->major, match->driver->minor) + 
> match->port->line;
> +
> + return dev->devt == devt; /* Actually, only one tty per port */
> +}
> +
>  int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
>  {
>   struct uart_state *state = drv->state + port->line;
> + struct device *tty_dev;
> + struct uart_match match = {port, drv};
>  
>   mutex_lock(>mutex);
>  
> @@ -1947,6 +1962,15 @@ int uart_suspend_port(struct uart_driver *drv, struct 
> uart_port *port)
>   }
>  #endif
>  
> + tty_dev = device_find_child(port->dev, , serial_match_port);
> + if (device_may_wakeup(tty_dev)) {
> + enable_irq_wake(port->irq);
> + put_device(tty_dev);
> + mutex_unlock(>mutex);
> + return 0;
> + }
> + port->suspended = 1;
> +
>   if (state->info && state->info->flags & UIF_INITIALIZED) {
>   const struct uart_ops *ops = port->ops;
>  
> @@ -1995,6 +2019,13 @@ int uart_resume_port(struct uart_driver *drv, struct 
> uart_port *port)
>   }
>  #endif
>  
> + if (!port->suspended) {
> + disable_irq_wake(port->irq);
> + mutex_unlock(>mutex);
> + return 0;
> + }
> + port->suspended = 0;
> +
>   uart_change_pm(state, 0);
>  
>   /*
> @@ -2266,6 +2297,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 +2333,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
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 773d8d8..60dedc0 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -291,7 +291,8 @@ struct uart_port {
>   unsigned long   mapbase;/* for ioremap */
>   struct device   *dev;   /* parent device */
>   unsigned char   hub6;   /* this should be in 
> the 8250 driver */
> - unsigned char   unused[3];
> + unsigned char   suspended;
> + unsigned char   unused[2];
>   void*private_data;  /* generic platform 
> data pointer */
>  };
>  
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] wake up from a serial port

2007-09-12 Thread Guennadi Liakhovetski
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]>

---

Following suggestions from Alan and Russell moved the may_wake_up checks 
to serial_core.c. This time actually tested - it does even work. Could 
someone, please, verify, that put_device after device_find_child is 
correct? Also would be nice to test with a Natsemi UART, that can wake up 
the system, if such systems exist.

Thanks
Guennadi

diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 9c57486..8a3d6ea 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1934,9 +1934,24 @@ static void uart_change_pm(struct uart_state *state, int 
pm_state)
}
 }
 
+struct uart_match {
+   struct uart_port *port;
+   struct uart_driver *driver;
+};
+
+static int serial_match_port(struct device *dev, void *data)
+{
+   struct uart_match *match = data;
+   dev_t devt = MKDEV(match->driver->major, match->driver->minor) + 
match->port->line;
+
+   return dev->devt == devt; /* Actually, only one tty per port */
+}
+
 int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
 {
struct uart_state *state = drv->state + port->line;
+   struct device *tty_dev;
+   struct uart_match match = {port, drv};
 
mutex_lock(>mutex);
 
@@ -1947,6 +1962,15 @@ int uart_suspend_port(struct uart_driver *drv, struct 
uart_port *port)
}
 #endif
 
+   tty_dev = device_find_child(port->dev, , serial_match_port);
+   if (device_may_wakeup(tty_dev)) {
+   enable_irq_wake(port->irq);
+   put_device(tty_dev);
+   mutex_unlock(>mutex);
+   return 0;
+   }
+   port->suspended = 1;
+
if (state->info && state->info->flags & UIF_INITIALIZED) {
const struct uart_ops *ops = port->ops;
 
@@ -1995,6 +2019,13 @@ int uart_resume_port(struct uart_driver *drv, struct 
uart_port *port)
}
 #endif
 
+   if (!port->suspended) {
+   disable_irq_wake(port->irq);
+   mutex_unlock(>mutex);
+   return 0;
+   }
+   port->suspended = 0;
+
uart_change_pm(state, 0);
 
/*
@@ -2266,6 +2297,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 +2333,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
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 773d8d8..60dedc0 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -291,7 +291,8 @@ struct uart_port {
unsigned long   mapbase;/* for ioremap */
struct device   *dev;   /* parent device */
unsigned char   hub6;   /* this should be in 
the 8250 driver */
-   unsigned char   unused[3];
+   unsigned char   suspended;
+   unsigned char   unused[2];
void*private_data;  /* generic platform 
data pointer */
 };
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] wake up from a serial port

2007-09-12 Thread Guennadi Liakhovetski
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]

---

Following suggestions from Alan and Russell moved the may_wake_up checks 
to serial_core.c. This time actually tested - it does even work. Could 
someone, please, verify, that put_device after device_find_child is 
correct? Also would be nice to test with a Natsemi UART, that can wake up 
the system, if such systems exist.

Thanks
Guennadi

diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 9c57486..8a3d6ea 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1934,9 +1934,24 @@ static void uart_change_pm(struct uart_state *state, int 
pm_state)
}
 }
 
+struct uart_match {
+   struct uart_port *port;
+   struct uart_driver *driver;
+};
+
+static int serial_match_port(struct device *dev, void *data)
+{
+   struct uart_match *match = data;
+   dev_t devt = MKDEV(match-driver-major, match-driver-minor) + 
match-port-line;
+
+   return dev-devt == devt; /* Actually, only one tty per port */
+}
+
 int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
 {
struct uart_state *state = drv-state + port-line;
+   struct device *tty_dev;
+   struct uart_match match = {port, drv};
 
mutex_lock(state-mutex);
 
@@ -1947,6 +1962,15 @@ int uart_suspend_port(struct uart_driver *drv, struct 
uart_port *port)
}
 #endif
 
+   tty_dev = device_find_child(port-dev, match, serial_match_port);
+   if (device_may_wakeup(tty_dev)) {
+   enable_irq_wake(port-irq);
+   put_device(tty_dev);
+   mutex_unlock(state-mutex);
+   return 0;
+   }
+   port-suspended = 1;
+
if (state-info  state-info-flags  UIF_INITIALIZED) {
const struct uart_ops *ops = port-ops;
 
@@ -1995,6 +2019,13 @@ int uart_resume_port(struct uart_driver *drv, struct 
uart_port *port)
}
 #endif
 
+   if (!port-suspended) {
+   disable_irq_wake(port-irq);
+   mutex_unlock(state-mutex);
+   return 0;
+   }
+   port-suspended = 0;
+
uart_change_pm(state, 0);
 
/*
@@ -2266,6 +2297,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 +2333,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
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 773d8d8..60dedc0 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -291,7 +291,8 @@ struct uart_port {
unsigned long   mapbase;/* for ioremap */
struct device   *dev;   /* parent device */
unsigned char   hub6;   /* this should be in 
the 8250 driver */
-   unsigned char   unused[3];
+   unsigned char   suspended;
+   unsigned char   unused[2];
void*private_data;  /* generic platform 
data pointer */
 };
 
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] wake up from a serial port

2007-09-12 Thread Andrew Morton
On Wed, 12 Sep 2007 20:50:10 +0200 (CEST)
Guennadi Liakhovetski [EMAIL PROTECTED] wrote:

 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]
 
 ---
 
 Following suggestions from Alan and Russell moved the may_wake_up checks 
 to serial_core.c. This time actually tested - it does even work. Could 
 someone, please, verify, that put_device after device_find_child is 
 correct?

Seems right to me, from reading device_find_child() and its associated
documentation.

 Also would be nice to test with a Natsemi UART, that can wake up 
 the system, if such systems exist.


It would help if you could provide simple-to-follow steps which a tester
should follow to perform this testing.

  
 diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
 index 9c57486..8a3d6ea 100644
 --- a/drivers/serial/serial_core.c
 +++ b/drivers/serial/serial_core.c
 @@ -1934,9 +1934,24 @@ static void uart_change_pm(struct uart_state *state, 
 int pm_state)
   }
  }
  
 +struct uart_match {
 + struct uart_port *port;
 + struct uart_driver *driver;
 +};
 +
 +static int serial_match_port(struct device *dev, void *data)
 +{
 + struct uart_match *match = data;
 + dev_t devt = MKDEV(match-driver-major, match-driver-minor) + 
 match-port-line;
 +
 + return dev-devt == devt; /* Actually, only one tty per port */
 +}
 +
  int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
  {
   struct uart_state *state = drv-state + port-line;
 + struct device *tty_dev;
 + struct uart_match match = {port, drv};
  
   mutex_lock(state-mutex);
  
 @@ -1947,6 +1962,15 @@ int uart_suspend_port(struct uart_driver *drv, struct 
 uart_port *port)
   }
  #endif
  
 + tty_dev = device_find_child(port-dev, match, serial_match_port);
 + if (device_may_wakeup(tty_dev)) {
 + enable_irq_wake(port-irq);
 + put_device(tty_dev);
 + mutex_unlock(state-mutex);
 + return 0;
 + }
 + port-suspended = 1;
 +
   if (state-info  state-info-flags  UIF_INITIALIZED) {
   const struct uart_ops *ops = port-ops;
  
 @@ -1995,6 +2019,13 @@ int uart_resume_port(struct uart_driver *drv, struct 
 uart_port *port)
   }
  #endif
  
 + if (!port-suspended) {
 + disable_irq_wake(port-irq);
 + mutex_unlock(state-mutex);
 + return 0;
 + }
 + port-suspended = 0;
 +
   uart_change_pm(state, 0);
  
   /*
 @@ -2266,6 +2297,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 +2333,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
 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
 index 773d8d8..60dedc0 100644
 --- a/include/linux/serial_core.h
 +++ b/include/linux/serial_core.h
 @@ -291,7 +291,8 @@ struct uart_port {
   unsigned long   mapbase;/* for ioremap */
   struct device   *dev;   /* parent device */
   unsigned char   hub6;   /* this should be in 
 the 8250 driver */
 - unsigned char   unused[3];
 + unsigned char   suspended;
 + unsigned char   unused[2];
   void*private_data;  /* generic platform 
 data pointer */
  };
  
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/