Skip to content

Commit

Permalink
firmware: drop bit ops in favor of simple state machine
Browse files Browse the repository at this point in the history
We track the state of the firmware loading with bit ops.  Since the
state machine has only a few states and they are all mutual exclusive
there are only a few simple state transition we can model this simplify.

	   UNKNOWN -> LOADING -> DONE | ABORTED

Because we don't use any bit ops on fw_state::status anymore we are able
to change the data type to enum fw_status and update the function
arguments accordingly.

READ_ONCE() and WRITE_ONCE() are propably not needed because there are a
lot of load and stores around fw_st->status. But let's make it explicit
and not be sorry later.

Cc: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Daniel Wagner authored and gregkh committed Nov 29, 2016
1 parent f52cc37 commit 0430caf
Showing 1 changed file with 5 additions and 7 deletions.
12 changes: 5 additions & 7 deletions drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static inline long firmware_loading_timeout(void)
*/
struct fw_state {
struct completion completion;
unsigned long status;
enum fw_status status;
};

static void fw_state_init(struct fw_state *fw_st)
Expand All @@ -123,7 +123,7 @@ static void fw_state_init(struct fw_state *fw_st)

static int __fw_state_check(struct fw_state *fw_st, enum fw_status status)
{
return test_bit(status, &fw_st->status);
return fw_st->status == status;
}

static long __fw_state_wait_common(struct fw_state *fw_st, long timeout)
Expand All @@ -132,7 +132,7 @@ static long __fw_state_wait_common(struct fw_state *fw_st, long timeout)

ret = wait_for_completion_interruptible_timeout(&fw_st->completion,
timeout);
if (ret != 0 && test_bit(FW_STATUS_ABORTED, &fw_st->status))
if (ret != 0 && READ_ONCE(fw_st->status) == FW_STATUS_ABORTED)
return -ENOENT;

return ret;
Expand All @@ -141,12 +141,10 @@ static long __fw_state_wait_common(struct fw_state *fw_st, long timeout)
static void __fw_state_set(struct fw_state *fw_st,
enum fw_status status)
{
set_bit(status, &fw_st->status);
WRITE_ONCE(fw_st->status, status);

if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) {
clear_bit(FW_STATUS_LOADING, &fw_st->status);
if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED)
complete_all(&fw_st->completion);
}
}

#define fw_state_start(fw_st) \
Expand Down

0 comments on commit 0430caf

Please sign in to comment.