1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2023-2026 Intel Corporation */ #ifndef _ISSEI_DEV_H_ #define _ISSEI_DEV_H_ #include <linux/device.h> #include <linux/mutex.h> #include <linux/sched.h> #include <linux/time64.h> #include <linux/types.h> #include <linux/wait.h> #include "dma.h" struct cdev; struct kset; struct issei_device; struct issei_host_client; extern struct class *issei_class; #define ISSEI_HOST_CLIENTS_MAX 255 #define ISSEI_SUPPORTED_PROTOCOL_VER 1 #define ISSEI_MAX_CONSEC_RESET 3 #define ISSEI_RST_HW_READY_TIMEOUT_MSEC (2 * MSEC_PER_SEC) #define ISSEI_RST_STEP_TIMEOUT_MSEC (2 * MSEC_PER_SEC) #define ISSEI_STOP_TIMEOUT_MSEC 500 #define ISSEI_WRITE_TIMEOUT_MSEC (MSEC_PER_SEC) /** * struct issei_write_buf - write buffer object * @list: linked list pointer * @cl: host client that requested this write * @data: data to write * @data_size: data size */ struct issei_write_buf { struct list_head list; struct issei_host_client *cl; const u8 *data; size_t data_size; }; /** * struct issei_hw_ops - callbacks for hardware operations * @irq_clear: clear irq * @irq_enable: enable irq * @irq_disable: disable irq * @irq_sync: sync irq * @hw_reset: initiate hardware reset * @hw_config: initial hardware config * @hw_is_ready: check if hardware is ready * @hw_reset_release: release hardware from reset * @host_set_ready: set host ready indicator * @setup_message_send: send setup message * @setup_message_recv: receive setup message * @irq_write_generate: generate interrupt on write complete */ struct issei_hw_ops { void (*irq_clear)(struct issei_device *idev); void (*irq_enable)(struct issei_device *idev); void (*irq_disable)(struct issei_device *idev); void (*irq_sync)(struct issei_device *idev); int (*hw_reset)(struct issei_device *idev, bool enable); int (*hw_config)(struct issei_device *idev); bool (*hw_is_ready)(struct issei_device *idev); void (*hw_reset_release)(struct issei_device *idev); void (*host_set_ready)(struct issei_device *idev); int (*setup_message_send)(struct issei_device *idev); int (*setup_message_recv)(struct issei_device *idev); int (*irq_write_generate)(struct issei_device *idev); }; /** * enum issei_rst_state: driver reset flow states * @ISSEI_RST_STATE_INIT: initial state * @ISSEI_RST_STATE_HW_READY: waiting for HW to be ready * @ISSEI_RST_STATE_SETUP: waiting for channel setup completion * @ISSEI_RST_STATE_START: waiting for start handshake completion * @ISSEI_RST_STATE_CLIENT_ENUM: waiting for client enumeration * @ISSEI_RST_STATE_DONE: reset flow is done * @ISSEI_RST_STATE_DISABLED: flow is disabled */ enum issei_rst_state { ISSEI_RST_STATE_INIT, ISSEI_RST_STATE_HW_READY, ISSEI_RST_STATE_SETUP, ISSEI_RST_STATE_START, ISSEI_RST_STATE_CLIENT_ENUM, ISSEI_RST_STATE_DONE, ISSEI_RST_STATE_DISABLED, }; /** * struct issei_device - issei device * @parent: parent device object * @dev: associated device object * @cdev: character device * @minor: allocated minor number * @wait_has_data: wait queue for data * @has_data: there are data to process * @power_down: device is powering down * @wait_rst_state: waitqueue for reset state processing * @rst_state: reset state * @fw_protocol_ver: protocol version * @fw_version: firmware version * @process_thread: worker thread * @reset_count: number of consecutive link reset attempts * @all_reset_count: cumilative number of link reset attempts * @client_lock: mutex to protect client lists and write queue * @host_client_list: host clients list * @host_client_last_id: last allocated host client id * @host_client_count: number of active host clients * @fw_client_list: firmware clients list * @write_queue: write queue * @last_write_ts: last write timestamp * @dma: DMA memory configuration * @ops: hardware operations * @hw: hw-specific data */ struct issei_device { struct device *parent; struct device dev; struct cdev *cdev; u32 minor; wait_queue_head_t wait_has_data; bool has_data; bool power_down; wait_queue_head_t wait_rst_state; enum issei_rst_state rst_state; u16 fw_protocol_ver; u16 fw_version[4]; /* reset flow */ struct task_struct *process_thread; u8 reset_count; u8 all_reset_count; /* clients */ struct mutex client_lock; struct list_head host_client_list; u16 host_client_last_id; u8 host_client_count; struct kset *fw_clients; struct list_head fw_client_list; struct list_head write_queue; ktime_t last_write_ts; struct issei_dma dma; const struct issei_hw_ops *ops; char hw[]; }; static inline void issei_poke_process_thread(struct issei_device *idev) { WRITE_ONCE(idev->has_data, true); wake_up_interruptible(&idev->wait_has_data); } int issei_start(struct issei_device *idev); void issei_stop(struct issei_device *idev); #endif /* _ISSEI_DEV_H_ */ |