From patchwork Mon Jun 27 14:30:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 921022 X-Patchwork-Delegate: jikos@jikos.cz Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5REV8XZ016430 for ; Mon, 27 Jun 2011 14:31:10 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752608Ab1F0ObJ (ORCPT ); Mon, 27 Jun 2011 10:31:09 -0400 Received: from mail-fx0-f52.google.com ([209.85.161.52]:59763 "EHLO mail-fx0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752552Ab1F0ObI (ORCPT ); Mon, 27 Jun 2011 10:31:08 -0400 Received: by mail-fx0-f52.google.com with SMTP id 18so1868751fxd.11 for ; Mon, 27 Jun 2011 07:31:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=WbJA+Xoa4CGH5wi0uU00WAYLqobVKsbsa7nRrsdP1X8=; b=ansze2ZQb5nY+vi4AqljyjXlCERp9j7eyGS9LrDu9ef71E+FDR9Um2pLIshQvBcB4W v7krjp7l62YntatUoOdCYc0v+PHxRBWWwmbP18ia0FpcwI5G2BCvlffStpxu9FiwsYHv 604iPkw943yWHciDplbpIzdnTYkvgfLwCwvco= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=D9Pvx+CUDl6dOmoLPyCZwmuukYbF3goaiW1cLixNJ6aNRnsdDFAMNK+KQZnPPf4fxW 9nuKLaNCzuLCbrb+LV/6tRcuKWFEEvik2stwcrgLL4say+HWbDbiRJO4tpyK7Xwe3Okf FntEmJ/xxBfA5y9qDizTIswjZvfpN6OnK+O+c= Received: by 10.223.98.82 with SMTP id p18mr9199908fan.64.1309185067924; Mon, 27 Jun 2011 07:31:07 -0700 (PDT) Received: from localhost.localdomain (stgt-5f73b179.pool.mediaWays.net [95.115.177.121]) by mx.google.com with ESMTPS id f3sm3570523faa.6.2011.06.27.07.31.06 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 27 Jun 2011 07:31:07 -0700 (PDT) From: David Herrmann To: linux-input@vger.kernel.org Cc: padovan@profusion.mobi, jkosina@suse.cz, oliver@neukum.org, David Herrmann Subject: [PATCH 11/12] HID: wiimote: Cache wiimote led state Date: Mon, 27 Jun 2011 16:30:12 +0200 Message-Id: <1309185013-484-11-git-send-email-dh.herrmann@googlemail.com> X-Mailer: git-send-email 1.7.5.2 In-Reply-To: <1309185013-484-1-git-send-email-dh.herrmann@googlemail.com> References: <1309185013-484-1-git-send-email-dh.herrmann@googlemail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 27 Jun 2011 14:31:10 +0000 (UTC) Save the current state of the leds in the wiimote data structure. This allows us to discard new led requests that wouldn't change anything. Protect the whole state structure by a spinlock. Every wiiproto_* function expects this spinlock to be held when called. Signed-off-by: David Herrmann --- drivers/hid/hid-wiimote.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c index 400a2d9..29a5b97 100644 --- a/drivers/hid/hid-wiimote.c +++ b/drivers/hid/hid-wiimote.c @@ -27,6 +27,11 @@ struct wiimote_buf { size_t size; }; +struct wiimote_state { + spinlock_t lock; + __u8 flags; +}; + struct wiimote_data { atomic_t ready; struct hid_device *hdev; @@ -37,12 +42,16 @@ struct wiimote_data { __u8 tail; struct wiimote_buf outq[WIIMOTE_BUFSIZE]; struct work_struct worker; + + struct wiimote_state state; }; #define WIIPROTO_FLAG_LED1 0x01 #define WIIPROTO_FLAG_LED2 0x02 #define WIIPROTO_FLAG_LED3 0x04 #define WIIPROTO_FLAG_LED4 0x08 +#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ + WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) enum wiiproto_reqs { WIIPROTO_REQ_LED = 0x11, @@ -168,6 +177,11 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) { __u8 cmd[2]; + leds &= WIIPROTO_FLAGS_LEDS; + if ((wdata->state.flags & WIIPROTO_FLAGS_LEDS) == leds) + return; + wdata->state.flags = (wdata->state.flags & ~WIIPROTO_FLAGS_LEDS) | leds; + cmd[0] = WIIPROTO_REQ_LED; cmd[1] = 0; @@ -240,6 +254,7 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, struct wiimote_data *wdata = hid_get_drvdata(hdev); struct wiiproto_handler *h; int i; + unsigned long flags; if (!atomic_read(&wdata->ready)) return -EBUSY; @@ -249,12 +264,16 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, if (size < 1) return -EINVAL; + spin_lock_irqsave(&wdata->state.lock, flags); + for (i = 0; handlers[i].id; ++i) { h = &handlers[i]; if (h->id == raw_data[0] && h->size < size) h->func(wdata, &raw_data[1]); } + spin_unlock_irqrestore(&wdata->state.lock, flags); + return 0; } @@ -292,6 +311,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev) spin_lock_init(&wdata->qlock); INIT_WORK(&wdata->worker, wiimote_worker); + spin_lock_init(&wdata->state.lock); + return wdata; } @@ -334,7 +355,12 @@ static int wiimote_hid_probe(struct hid_device *hdev, smp_wmb(); atomic_set(&wdata->ready, 1); hid_info(hdev, "New device registered\n"); + + /* by default set led1 after device initialization */ + spin_lock_irq(&wdata->state.lock); wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1); + spin_unlock_irq(&wdata->state.lock); + return 0; err_stop: