From patchwork Tue Jun 10 20:11:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reyad Attiyat X-Patchwork-Id: 4331511 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9B29BBEEAA for ; Tue, 10 Jun 2014 20:12:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A82BB20274 for ; Tue, 10 Jun 2014 20:12:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A845D20251 for ; Tue, 10 Jun 2014 20:12:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755926AbaFJULw (ORCPT ); Tue, 10 Jun 2014 16:11:52 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:63422 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755924AbaFJULu (ORCPT ); Tue, 10 Jun 2014 16:11:50 -0400 Received: by mail-pa0-f45.google.com with SMTP id hz1so1061281pad.4 for ; Tue, 10 Jun 2014 13:11:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=6Erx2f+ZUCQh5AqJJZpPHzlTL5/MYS36cOpxsC0ounY=; b=QvqCdU5UyOFim80JcWEHy1dY1Z+j+T9hmAHswSFRc5v4ADZ/ZkKBWsYQsBq7hEkrYy 5dH/iPp4Mj8loAsccK6Re5lCrCGUN35CGOf7gH336PxBFJyyZ5RuLb+anJzIk5xUlAF+ r11MNndHmJXveBuWvDNEQ/lzhoBsPHji//YC/GTyxBdPVbscj1LtvIE8arO0UMG3jlOg gbMaq/3+JW9YjKKg0FXRjEsJhROgT8Q9rtTUCDock/hfQdtQ2Ts5KEnRsfaOZkpbL7h4 +EMBRzT4+5RFIdFdq8oqW8b2G1gd8v9Wp4rtU+9MMXDlKz8/fLVK8ODOpYmdbI9l6hHm 5PFA== X-Received: by 10.68.237.133 with SMTP id vc5mr14180517pbc.92.1402431110233; Tue, 10 Jun 2014 13:11:50 -0700 (PDT) Received: from localhost.net (S01066805ca01c45c.wp.shawcable.net. [24.76.189.120]) by mx.google.com with ESMTPSA id au4sm71062214pbc.10.2014.06.10.13.11.48 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Jun 2014 13:11:49 -0700 (PDT) From: Reyad Attiyat To: linux-kernel@vger.kernel.org, srinivas.pandruvada@linux.intel.com, jkosina@suse.cz, linux-input@vger.kernel.org Cc: Reyad Attiyat Subject: [PATCH] HID: hid-sensor-hub: Make all locks of dyn_callback_lock disable interrupts. Date: Tue, 10 Jun 2014 15:11:37 -0500 Message-Id: <1402431097-3883-1-git-send-email-reyad.attiyat@gmail.com> X-Mailer: git-send-email 1.9.3 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The dynamic callback lock (dyn_callback_lock) must not be interrupted when locked because the lock is used in the interrupt handler function sensor_hub_raw_event(). Signed-off-by: Reyad Attiyat --- drivers/hid/hid-sensor-hub.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index a8d5c8f..6547138 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -133,10 +133,11 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( struct hid_sensor_hub_device **hsdev, void **priv) { + unsigned long flags; struct hid_sensor_hub_callbacks_list *callback; struct sensor_hub_data *pdata = hid_get_drvdata(hdev); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) if (callback->usage_id == usage_id && (collection_index >= @@ -145,10 +146,10 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( callback->hsdev->end_collection_index)) { *priv = callback->priv; *hsdev = callback->hsdev; - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return callback->usage_callback; } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return NULL; } @@ -157,19 +158,20 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, u32 usage_id, struct hid_sensor_hub_callbacks *usage_callback) { + unsigned long flags; struct hid_sensor_hub_callbacks_list *callback; struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) if (callback->usage_id == usage_id && callback->hsdev == hsdev) { - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return -EINVAL; } callback = kzalloc(sizeof(*callback), GFP_ATOMIC); if (!callback) { - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return -ENOMEM; } callback->hsdev = hsdev; @@ -177,7 +179,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, callback->usage_id = usage_id; callback->priv = NULL; list_add_tail(&callback->list, &pdata->dyn_callback_list); - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } @@ -186,10 +188,11 @@ EXPORT_SYMBOL_GPL(sensor_hub_register_callback); int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, u32 usage_id) { + unsigned long flags; struct hid_sensor_hub_callbacks_list *callback; struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) if (callback->usage_id == usage_id && callback->hsdev == hsdev) { @@ -197,7 +200,7 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, kfree(callback); break; } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } @@ -376,34 +379,36 @@ EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info); #ifdef CONFIG_PM static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message) { + unsigned long flags; struct sensor_hub_data *pdata = hid_get_drvdata(hdev); struct hid_sensor_hub_callbacks_list *callback; hid_dbg(hdev, " sensor_hub_suspend\n"); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) { if (callback->usage_callback->suspend) callback->usage_callback->suspend( callback->hsdev, callback->priv); } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } static int sensor_hub_resume(struct hid_device *hdev) { + unsigned long flags; struct sensor_hub_data *pdata = hid_get_drvdata(hdev); struct hid_sensor_hub_callbacks_list *callback; hid_dbg(hdev, " sensor_hub_resume\n"); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) { if (callback->usage_callback->resume) callback->usage_callback->resume( callback->hsdev, callback->priv); } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; }