/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2023-2026 Intel Corporation */ #ifndef _ISSEI_DEV_H_ #define _ISSEI_DEV_H_ #include #include #include #include #include #include #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_ */