162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
462306a36Sopenharmony_ci * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/*
862306a36Sopenharmony_ci * Generic state machine framework.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#include "efc.h"
1162306a36Sopenharmony_ci#include "efc_sm.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/**
1462306a36Sopenharmony_ci * efc_sm_post_event() - Post an event to a context.
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * @ctx: State machine context
1762306a36Sopenharmony_ci * @evt: Event to post
1862306a36Sopenharmony_ci * @data: Event-specific data (if any)
1962306a36Sopenharmony_ci */
2062306a36Sopenharmony_ciint
2162306a36Sopenharmony_ciefc_sm_post_event(struct efc_sm_ctx *ctx,
2262306a36Sopenharmony_ci		  enum efc_sm_event evt, void *data)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	if (!ctx->current_state)
2562306a36Sopenharmony_ci		return -EIO;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	ctx->current_state(ctx, evt, data);
2862306a36Sopenharmony_ci	return 0;
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_civoid
3262306a36Sopenharmony_ciefc_sm_transition(struct efc_sm_ctx *ctx,
3362306a36Sopenharmony_ci		  void (*state)(struct efc_sm_ctx *,
3462306a36Sopenharmony_ci				enum efc_sm_event, void *), void *data)
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	if (ctx->current_state == state) {
3862306a36Sopenharmony_ci		efc_sm_post_event(ctx, EFC_EVT_REENTER, data);
3962306a36Sopenharmony_ci	} else {
4062306a36Sopenharmony_ci		efc_sm_post_event(ctx, EFC_EVT_EXIT, data);
4162306a36Sopenharmony_ci		ctx->current_state = state;
4262306a36Sopenharmony_ci		efc_sm_post_event(ctx, EFC_EVT_ENTER, data);
4362306a36Sopenharmony_ci	}
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic char *event_name[] = EFC_SM_EVENT_NAME;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciconst char *efc_sm_event_name(enum efc_sm_event evt)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	if (evt > EFC_EVT_LAST)
5162306a36Sopenharmony_ci		return "unknown";
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	return event_name[evt];
5462306a36Sopenharmony_ci}
55