1 /* SPDX-License-Identifier: GPL-2.0-only 2 * 3 * Copyright (c) 2021, MediaTek Inc. 4 * Copyright (c) 2021-2022, Intel Corporation. 5 * 6 * Authors: 7 * Amir Hanania <amir.hanania@intel.com> 8 * Haijun Liu <haijun.liu@mediatek.com> 9 * Moises Veleta <moises.veleta@intel.com> 10 * 11 * Contributors: 12 * Eliot Lee <eliot.lee@intel.com> 13 * Ricardo Martinez <ricardo.martinez@linux.intel.com> 14 * Sreehari Kancharla <sreehari.kancharla@intel.com> 15 */ 16 17 #ifndef __T7XX_MONITOR_H__ 18 #define __T7XX_MONITOR_H__ 19 20 #include <linux/bits.h> 21 #include <linux/sched.h> 22 #include <linux/spinlock.h> 23 #include <linux/types.h> 24 #include <linux/wait.h> 25 26 #include "t7xx_modem_ops.h" 27 28 enum t7xx_fsm_state { 29 FSM_STATE_INIT, 30 FSM_STATE_PRE_START, 31 FSM_STATE_STARTING, 32 FSM_STATE_READY, 33 FSM_STATE_EXCEPTION, 34 FSM_STATE_STOPPING, 35 FSM_STATE_STOPPED, 36 }; 37 38 enum t7xx_fsm_event_state { 39 FSM_EVENT_INVALID, 40 FSM_EVENT_MD_HS2, 41 FSM_EVENT_AP_HS2, 42 FSM_EVENT_MD_EX, 43 FSM_EVENT_MD_EX_REC_OK, 44 FSM_EVENT_MD_EX_PASS, 45 FSM_EVENT_MD_HS2_EXIT, 46 FSM_EVENT_AP_HS2_EXIT, 47 FSM_EVENT_MAX 48 }; 49 50 enum t7xx_fsm_cmd_state { 51 FSM_CMD_INVALID, 52 FSM_CMD_START, 53 FSM_CMD_EXCEPTION, 54 FSM_CMD_PRE_STOP, 55 FSM_CMD_STOP, 56 }; 57 58 enum t7xx_ex_reason { 59 EXCEPTION_HS_TIMEOUT, 60 EXCEPTION_EVENT, 61 }; 62 63 enum t7xx_md_irq_type { 64 MD_IRQ_WDT, 65 MD_IRQ_CCIF_EX, 66 MD_IRQ_PORT_ENUM, 67 }; 68 69 enum md_state { 70 MD_STATE_INVALID, 71 MD_STATE_WAITING_FOR_HS1, 72 MD_STATE_WAITING_FOR_HS2, 73 MD_STATE_READY, 74 MD_STATE_EXCEPTION, 75 MD_STATE_WAITING_TO_STOP, 76 MD_STATE_STOPPED, 77 }; 78 79 #define FSM_CMD_FLAG_WAIT_FOR_COMPLETION BIT(0) 80 #define FSM_CMD_FLAG_FLIGHT_MODE BIT(1) 81 #define FSM_CMD_FLAG_IN_INTERRUPT BIT(2) 82 #define FSM_CMD_EX_REASON GENMASK(23, 16) 83 84 struct t7xx_fsm_ctl { 85 struct t7xx_modem *md; 86 enum md_state md_state; 87 unsigned int curr_state; 88 struct list_head command_queue; 89 struct list_head event_queue; 90 wait_queue_head_t command_wq; 91 wait_queue_head_t event_wq; 92 wait_queue_head_t async_hk_wq; 93 spinlock_t event_lock; /* Protects event queue */ 94 spinlock_t command_lock; /* Protects command queue */ 95 struct task_struct *fsm_thread; 96 bool exp_flg; 97 spinlock_t notifier_lock; /* Protects notifier list */ 98 struct list_head notifier_list; 99 }; 100 101 struct t7xx_fsm_event { 102 struct list_head entry; 103 enum t7xx_fsm_event_state event_id; 104 unsigned int length; 105 unsigned char data[] __counted_by(length); 106 }; 107 108 struct t7xx_fsm_command { 109 struct list_head entry; 110 enum t7xx_fsm_cmd_state cmd_id; 111 unsigned int flag; 112 struct completion *done; 113 int *ret; 114 }; 115 116 struct t7xx_fsm_notifier { 117 struct list_head entry; 118 int (*notifier_fn)(enum md_state state, void *data); 119 void *data; 120 }; 121 122 int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, 123 unsigned int flag); 124 int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id, 125 unsigned char *data, unsigned int length); 126 void t7xx_fsm_clr_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id); 127 void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state); 128 void t7xx_fsm_reset(struct t7xx_modem *md); 129 int t7xx_fsm_init(struct t7xx_modem *md); 130 void t7xx_fsm_uninit(struct t7xx_modem *md); 131 int t7xx_fsm_recv_md_intr(struct t7xx_fsm_ctl *ctl, enum t7xx_md_irq_type type); 132 enum md_state t7xx_fsm_get_md_state(struct t7xx_fsm_ctl *ctl); 133 unsigned int t7xx_fsm_get_ctl_state(struct t7xx_fsm_ctl *ctl); 134 void t7xx_fsm_notifier_register(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier); 135 void t7xx_fsm_notifier_unregister(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier); 136 137 #endif /* __T7XX_MONITOR_H__ */ 138