public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Soeren Sonnenburg <kernel@nn7.de>
To: Linux Kernel <linux-kernel@vger.kernel.org>
Cc: Oliver Neukum <oliver@neukum.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Jiri Kosina <jikos@jikos.cz>
Subject: converting appletouch to usb autosuspend again...
Date: Sat, 23 Aug 2008 21:00:18 +0000	[thread overview]
Message-ID: <1219525218.8221.31.camel@localhost> (raw)

[-- Attachment #1: Type: text/plain, Size: 856 bytes --]

Dear all,

I wonder whether anyone else tried to get appletouch usb autosuspend to
work. I've seen Oliver's patch but as it kept oopsing on me and I
couldn't parse the usb_mark_last_busy logic I came up with the attached
patch against (current git; at least didn't oops for me over the last
several days and suspend/resume cycles).

However things I don't understand, 

a) is autosuspend on the appletouch driver used at all (how can I find
out)

b) do I need dev->intf->needs_remote_wakeup = 1; ?

c) is line 33 in the patch safe to do ?

And while we are at it I am still seeing these X falls back to hid mouse
mode, only switching to console and back resolves this (looks like this
only worked in previous kernels as resume from s2ram took a lot longer
due to the IDE driver doing a couple of resets) - is there anything one
could do about it?

Soeren


[-- Attachment #2: appletouch_autosuspend.diff --]
[-- Type: text/x-patch, Size: 3921 bytes --]

diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 1f41ae9..19003c8 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb/input.h>
+#include <linux/mutex.h>
 
 /* Type of touchpad */
 enum atp_touchpad_type {
@@ -140,10 +141,12 @@ MODULE_DEVICE_TABLE(usb, atp_table);
 struct atp {
 	char			phys[64];
 	struct usb_device	*udev;		/* usb device */
+	struct usb_interface	*intf;		/* our interface */
 	struct urb		*urb;		/* usb request block */
 	signed char		*data;		/* transferred data */
 	struct input_dev	*input;		/* input dev */
 	enum atp_touchpad_type	type;		/* type of touchpad */
+	struct mutex		pm_mutex;	/* serialize access to open/suspend */
 	bool			open;
 	bool			valid;		/* are the samples valid? */
 	bool			size_detect_done;
@@ -259,6 +262,11 @@ static void atp_reinit(struct work_struct *work)
 	if (retval)
 		err("atp_reinit: usb_submit_urb failed with error %d",
 		    retval);
+
+	/* device is idle and available for autosuspend */
+	mutex_lock(&dev->pm_mutex);
+	usb_autopm_disable(dev->intf);
+	mutex_unlock(&dev->pm_mutex);
 }
 
 static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
@@ -547,21 +555,37 @@ static void atp_complete(struct urb *urb)
 static int atp_open(struct input_dev *input)
 {
 	struct atp *dev = input_get_drvdata(input);
+	int error = usb_autopm_get_interface(dev->intf);
+	if (error)
+		return error;
 
-	if (usb_submit_urb(dev->urb, GFP_ATOMIC))
-		return -EIO;
+	mutex_lock(&dev->pm_mutex);
+	error=usb_submit_urb(dev->urb, GFP_ATOMIC);
 
-	dev->open = 1;
-	return 0;
+	if (!error)
+	    dev->open = 1;
+
+	mutex_unlock(&dev->pm_mutex);
+
+	if (error)
+		usb_autopm_put_interface(dev->intf);
+
+	return error;
 }
 
 static void atp_close(struct input_dev *input)
 {
 	struct atp *dev = input_get_drvdata(input);
 
+	mutex_lock(&dev->pm_mutex);
+
 	usb_kill_urb(dev->urb);
 	cancel_work_sync(&dev->work);
 	dev->open = 0;
+
+	mutex_unlock(&dev->pm_mutex);
+
+	usb_autopm_put_interface(dev->intf);
 }
 
 static int atp_handle_geyser(struct atp *dev)
@@ -615,9 +639,12 @@ static int atp_probe(struct usb_interface *iface,
 	}
 
 	dev->udev = udev;
+	dev->intf = iface;
 	dev->input = input_dev;
 	dev->type = id->driver_info;
 	dev->overflow_warned = false;
+	mutex_init(&dev->pm_mutex);
+
 	if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1)
 		dev->datalen = 81;
 	else
@@ -750,27 +777,41 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
 {
 	struct atp *dev = usb_get_intfdata(iface);
 
+	mutex_lock(&dev->pm_mutex);
+
 	usb_kill_urb(dev->urb);
 	dev->valid = false;
 
+	mutex_unlock(&dev->pm_mutex);
+
 	return 0;
 }
 
 static int atp_resume(struct usb_interface *iface)
 {
 	struct atp *dev = usb_get_intfdata(iface);
+	int error = 0;
 
-	if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
-		return -EIO;
+	mutex_lock(&dev->pm_mutex);
 
-	return 0;
+	if (dev->open)
+	    error = usb_submit_urb(dev->urb, GFP_ATOMIC);
+
+	mutex_unlock(&dev->pm_mutex);
+
+	return error;
 }
 
 static int atp_reset_resume(struct usb_interface *iface)
 {
 	struct atp *dev = usb_get_intfdata(iface);
+	int error = 0;
 
-	return atp_recover(dev);
+	mutex_lock(&dev->pm_mutex);
+	error = atp_recover(dev);
+	mutex_unlock(&dev->pm_mutex);
+
+	return error;
 }
 
 static struct usb_driver atp_driver = {
@@ -781,6 +822,7 @@ static struct usb_driver atp_driver = {
 	.resume		= atp_resume,
 	.reset_resume	= atp_reset_resume,
 	.id_table	= atp_table,
+	.supports_autosuspend	= 1,
 };
 
 static int __init atp_init(void)
@@ -795,3 +837,4 @@ static void __exit atp_exit(void)
 
 module_init(atp_init);
 module_exit(atp_exit);
+

             reply	other threads:[~2008-08-24 17:56 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-23 21:00 Soeren Sonnenburg [this message]
2008-08-24 18:39 ` converting appletouch to usb autosuspend again Oliver Neukum
2008-08-28 15:41   ` Soeren Sonnenburg
  -- strict thread matches above, loose matches on Subject: below --
2008-08-25  4:22 Justin Mattock
2008-08-25  6:40 ` converting " Oliver Neukum
2008-08-25  7:08   ` Justin Mattock
2008-08-25  7:32     ` Oliver Neukum
2008-08-25 14:23       ` Justin Mattock

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1219525218.8221.31.camel@localhost \
    --to=kernel@nn7.de \
    --cc=jikos@jikos.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oliver@neukum.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox