[rft]basic suspend/resume for option driver

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

 



Hi,

this is very basic suspend/resume for the option driver.
It compiles, otherwise it is untested.

	Regards
		Oliver

---

commit 3b9d9d1f45d59f7109ffa5a4c5407c1c4cac5207
Author: Oliver Neukum <oneukum@xxxxxxx>
Date:   Wed Jan 14 19:12:29 2009 +0100

    very basic suspend/resume for the option driver

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 30ae72e..2c91e3d 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -62,6 +62,8 @@ static int  option_tiocmget(struct tty_struct *tty, struct file *file);
 static int  option_tiocmset(struct tty_struct *tty, struct file *file,
 				unsigned int set, unsigned int clear);
 static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
+static int  option_suspend(struct usb_interface *intf, pm_message_t message);
+static int  option_resume(struct usb_interface *intf);
 
 /* Vendor and product IDs */
 #define OPTION_VENDOR_ID			0x0AF0
@@ -487,6 +489,8 @@ static struct usb_driver option_driver = {
 	.name       = "option",
 	.probe      = usb_serial_probe,
 	.disconnect = usb_serial_disconnect,
+	.suspend    = option_suspend,
+	.resume     = option_resume,
 	.id_table   = option_ids,
 	.no_dynamic_id = 	1,
 };
@@ -1068,14 +1072,12 @@ bail_out_error:
 	return 1;
 }
 
-static void option_shutdown(struct usb_serial *serial)
+static void stop_read_write_urbs(struct usb_serial *serial)
 {
 	int i, j;
 	struct usb_serial_port *port;
 	struct option_port_private *portdata;
 
-	dbg("%s", __func__);
-
 	/* Stop reading/writing urbs */
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
@@ -1084,7 +1086,18 @@ static void option_shutdown(struct usb_serial *serial)
 			usb_kill_urb(portdata->in_urbs[j]);
 		for (j = 0; j < N_OUT_URB; j++)
 			usb_kill_urb(portdata->out_urbs[j]);
-	}
+	}	
+}
+
+static void option_shutdown(struct usb_serial *serial)
+{
+	int i, j;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
+
+	dbg("%s", __func__);
+
+	stop_read_write_urbs(serial);
 
 	/* Now free them */
 	for (i = 0; i < serial->num_ports; ++i) {
@@ -1115,6 +1128,62 @@ static void option_shutdown(struct usb_serial *serial)
 	}
 }
 
+static int option_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct usb_serial_port *port;
+	struct usb_serial *serial = usb_get_intfdata(intf);
+	int i;
+
+	stop_read_write_urbs(serial);
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		usb_kill_urb(port->interrupt_in_urb);
+	}
+	return 0;
+}
+
+static int option_resume(struct usb_interface *intf)
+{
+	int err, i, j;
+	struct usb_serial_port *port;
+	struct urb *urb;
+	struct option_port_private *portdata;
+	struct usb_serial *serial = usb_get_intfdata(intf);
+
+	/* get the interrupt URBs resubmitted unconditionally */
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
+		if (err < 0)
+			return err;
+	}
+
+	for (i = 0; i < serial->num_ports; i++) {
+		/* walk all ports */
+		port = serial->port[i];
+		portdata = usb_get_serial_port_data(port);
+		mutex_lock(&port->mutex);
+
+		/* skip closed ports */
+		if (!port->port.count) {
+			mutex_unlock(&port->mutex);
+			continue;
+		}
+
+		for (j = 0; j < N_IN_URB; j++) {
+			urb = portdata->in_urbs[j];
+			err = usb_submit_urb(urb, GFP_NOIO);
+			if (err < 0) {
+				mutex_unlock(&port->mutex);
+				return err;
+			}
+		}
+		mutex_unlock(&port->mutex);
+	}
+	return 0;
+}
+
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux