From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933301AbcHWJBu (ORCPT ); Tue, 23 Aug 2016 05:01:50 -0400 Received: from atlantic540.startdedicated.de ([188.138.9.77]:51877 "EHLO atlantic540.startdedicated.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757574AbcHWJBC (ORCPT ); Tue, 23 Aug 2016 05:01:02 -0400 From: Daniel Wagner To: linux-kernel@vger.kernel.org Cc: Daniel Wagner , Ming Lei , "Luis R . Rodriguez" , Greg Kroah-Hartman Subject: [PATCH v2 2/2] firmware_class: Use swait instead of completion Date: Tue, 23 Aug 2016 11:00:20 +0200 Message-Id: <1471942820-23767-3-git-send-email-wagi@monom.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1471942820-23767-1-git-send-email-wagi@monom.org> References: <1471942820-23767-1-git-send-email-wagi@monom.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Daniel Wagner complete_all() can only be issued once before it needs to be reinitialized. To ensure we never call complete_all() twice we use swait and make the code here a bit more robust. Signed-off-by: Daniel Wagner Cc: Ming Lei Cc: Luis R. Rodriguez Cc: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d3dcf87..029b829 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -109,13 +110,13 @@ enum { struct fw_status { unsigned long status; - struct completion completion; + struct swait_queue_head wq; }; static void fw_status_init(struct fw_status *fw_st) { fw_st->status = FW_STATUS_UNKNOWN; - init_completion(&fw_st->completion); + init_swait_queue_head(&fw_st->wq); } static unsigned long __fw_status_get(struct fw_status *fw_st) @@ -123,15 +124,19 @@ static unsigned long __fw_status_get(struct fw_status *fw_st) return READ_ONCE(fw_st->status); } +static inline bool is_fw_status_done(unsigned long status) +{ + return status == FW_STATUS_DONE || + status == FW_STATUS_ABORTED; +} + static int fw_status_wait_timeout(struct fw_status *fw_st, long timeout) { - unsigned long status; int err; - - err = wait_for_completion_interruptible_timeout(&fw_st->completion, - timeout); - status = READ_ONCE(fw_st->status); - if (err == 0 && status == FW_STATUS_ABORTED) + err = swait_event_interruptible_timeout(fw_st->wq, + is_fw_status_done(READ_ONCE(fw_st->status)), + timeout); + if (err == 0 && fw_st->status == FW_STATUS_ABORTED) return -ENOENT; return err; @@ -144,7 +149,7 @@ static void __fw_status_set(struct fw_status *fw_st, if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) - complete_all(&fw_st->completion); + swake_up(&fw_st->wq); } #define fw_status_start(fw_st) \ -- 2.7.4