From patchwork Mon Jan 18 14:14:25 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bastien Nocera X-Patchwork-Id: 73661 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0IEEY1W020737 for ; Mon, 18 Jan 2010 14:14:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752300Ab0AROOe (ORCPT ); Mon, 18 Jan 2010 09:14:34 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752305Ab0AROOe (ORCPT ); Mon, 18 Jan 2010 09:14:34 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49070 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752297Ab0AROOc (ORCPT ); Mon, 18 Jan 2010 09:14:32 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o0IEESwg002008 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 18 Jan 2010 09:14:28 -0500 Received: from [10.36.8.89] (vpn2-8-89.ams2.redhat.com [10.36.8.89]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o0IEEQGC015273; Mon, 18 Jan 2010 09:14:27 -0500 Subject: [PATCHes] Apple IR receiver driver From: Bastien Nocera To: linux-input@vger.kernel.org Cc: Dmitry Torokhov , Matthew Garrett , Tino Keitel Date: Mon, 18 Jan 2010 14:14:25 +0000 Message-ID: <1263824065.20565.2730.camel@localhost.localdomain> Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From 39309f376a988b7a5c37e9ef82e9cd6c87af2e97 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 18 Jan 2010 13:57:03 +0000 Subject: [PATCH 2/2] [appleir] Add suspend support Close the connection to the device and kill the timer when suspending, and undo those changes on resume. Signed-off-by: Bastien Nocera --- drivers/input/misc/appleir.c | 120 +++++++++++++++++++++++++++++++++++++++--- 1 files changed, 112 insertions(+), 8 deletions(-) diff --git a/drivers/input/misc/appleir.c b/drivers/input/misc/appleir.c index 54a9647..f03db3e 100644 --- a/drivers/input/misc/appleir.c +++ b/drivers/input/misc/appleir.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ struct appleir { u8 *data; dma_addr_t dma_buf; struct usb_device *usbdev; + unsigned int flags; struct urb *urb; int timer_initted; struct timer_list key_up_timer; @@ -60,6 +62,13 @@ struct appleir { char phys[32]; }; +static DEFINE_MUTEX(appleir_mutex); + +enum { + APPLEIR_OPENED = 0x1, + APPLEIR_SUSPENDED = 0x2, +}; + static struct usb_device_id appleir_ids[] = { {USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL)}, {USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4)}, @@ -223,19 +232,50 @@ static void appleir_urb(struct urb *urb) static int appleir_open(struct input_dev *dev) { struct appleir *appleir = input_get_drvdata(dev); + struct usb_interface *intf = usb_ifnum_to_if(appleir->usbdev, 0); + int r; + + r = usb_autopm_get_interface(intf); + if (r) { + dev_err(&intf->dev, + "%s(): usb_autopm_get_interface() = %d\n", __func__, r); + return r; + } + + mutex_lock(&appleir_mutex); - if (usb_submit_urb(appleir->urb, GFP_KERNEL)) - return -EIO; + if (usb_submit_urb(appleir->urb, GFP_KERNEL)) { + r = -EIO; + goto fail; + } + + appleir->flags |= APPLEIR_OPENED; + + mutex_unlock(&appleir_mutex); + + usb_autopm_put_interface(intf); return 0; +fail: + mutex_unlock(&appleir_mutex); + usb_autopm_put_interface(intf); + return r; } static void appleir_close(struct input_dev *dev) { struct appleir *appleir = input_get_drvdata(dev); - usb_kill_urb(appleir->urb); - del_timer_sync(&appleir->key_up_timer); + mutex_lock(&appleir_mutex); + + if (!(appleir->flags & APPLEIR_SUSPENDED)) { + usb_kill_urb(appleir->urb); + del_timer_sync(&appleir->key_up_timer); + } + + appleir->flags &= ~APPLEIR_OPENED; + + mutex_unlock(&appleir_mutex); } static int appleir_probe(struct usb_interface *intf, @@ -350,11 +390,75 @@ static void appleir_disconnect(struct usb_interface *intf) } } +static int appleir_suspend(struct usb_interface *interface, + pm_message_t message) +{ + struct appleir *appleir; +/* struct usb_host_interface *alt = interface->cur_altsetting; + + if (alt->desc.bInterfaceNumber) + return 0; */ + + appleir = usb_get_intfdata(interface); + + mutex_lock(&appleir_mutex); + + if (appleir->flags & APPLEIR_OPENED) { + usb_kill_urb(appleir->urb); + del_timer_sync(&appleir->key_up_timer); + } + + appleir->flags |= APPLEIR_SUSPENDED; + + mutex_unlock(&appleir_mutex); + + return 0; +} + +static int appleir_resume(struct usb_interface *interface) +{ + struct appleir *appleir; + /* struct usb_host_interface *alt = interface->cur_altsetting; + + if (alt->desc.bInterfaceNumber) + return 0; */ + + appleir = usb_get_intfdata(interface); + + mutex_lock(&appleir_mutex); + + if (appleir->flags & APPLEIR_OPENED) { + struct usb_endpoint_descriptor *endpoint; + + endpoint = &interface->cur_altsetting->endpoint[0].desc; + usb_fill_int_urb(appleir->urb, appleir->usbdev, + usb_rcvintpipe(appleir->usbdev, endpoint->bEndpointAddress), + appleir->data, 8, + appleir_urb, appleir, endpoint->bInterval); + appleir->urb->transfer_dma = appleir->dma_buf; + appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + init_timer(&appleir->key_up_timer); + + appleir->key_up_timer.function = key_up_tick; + appleir->key_up_timer.data = (unsigned long)appleir; + } + + appleir->flags &= ~APPLEIR_SUSPENDED; + + mutex_unlock(&appleir_mutex); + + return 0; +} + static struct usb_driver appleir_driver = { - .name = "appleir", - .probe = appleir_probe, - .disconnect = appleir_disconnect, - .id_table = appleir_ids, + .name = "appleir", + .probe = appleir_probe, + .disconnect = appleir_disconnect, + .suspend = appleir_suspend, + .resume = appleir_resume, + .reset_resume = appleir_resume, + .id_table = appleir_ids, }; static int __init appleir_init(void) -- 1.6.5.2