// SPDX-License-Identifier: GPL-2.0-only /* * ISHTP bus layer messages handling * * Copyright (c) 2003-2016, Intel Corporation. */ #include <linux/export.h> #include <linux/slab.h> #include <linux/sched.h> #include <linux/wait.h> #include <linux/spinlock.h> #include "ishtp-dev.h" #include "hbm.h" #include "client.h" #include "loader.h" /** * ishtp_hbm_fw_cl_allocate() - Allocate FW clients * @dev: ISHTP device instance * * Allocates storage for fw clients */ static void ishtp_hbm_fw_cl_allocate(struct ishtp_device *dev) { … } /** * ishtp_hbm_cl_hdr() - construct client hbm header * @cl: client * @hbm_cmd: host bus message command * @buf: buffer for cl header * @len: buffer length * * Initialize HBM buffer */ static inline void ishtp_hbm_cl_hdr(struct ishtp_cl *cl, uint8_t hbm_cmd, void *buf, size_t len) { … } /** * ishtp_hbm_cl_addr_equal() - Compare client address * @cl: client * @buf: Client command buffer * * Compare client address with the address in command buffer * * Return: True if they have the same address */ static inline bool ishtp_hbm_cl_addr_equal(struct ishtp_cl *cl, void *buf) { … } /** * ishtp_hbm_start_wait() - Wait for HBM start message * @dev: ISHTP device instance * * Wait for HBM start message from firmware * * Return: 0 if HBM start is/was received else timeout error */ int ishtp_hbm_start_wait(struct ishtp_device *dev) { … } /** * ishtp_hbm_start_req() - Send HBM start message * @dev: ISHTP device instance * * Send HBM start message to firmware * * Return: 0 if success else error code */ int ishtp_hbm_start_req(struct ishtp_device *dev) { … } /** * ishtp_hbm_enum_clients_req() - Send client enum req * @dev: ISHTP device instance * * Send enumeration client request message * * Return: 0 if success else error code */ void ishtp_hbm_enum_clients_req(struct ishtp_device *dev) { … } /** * ishtp_hbm_prop_req() - Request property * @dev: ISHTP device instance * * Request property for a single client * * Return: 0 if success else error code */ static int ishtp_hbm_prop_req(struct ishtp_device *dev) { … } /** * ishtp_hbm_stop_req() - Send HBM stop * @dev: ISHTP device instance * * Send stop request message */ static void ishtp_hbm_stop_req(struct ishtp_device *dev) { … } /** * ishtp_hbm_cl_flow_control_req() - Send flow control request * @dev: ISHTP device instance * @cl: ISHTP client instance * * Send flow control request * * Return: 0 if success else error code */ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev, struct ishtp_cl *cl) { … } /** * ishtp_hbm_cl_disconnect_req() - Send disconnect request * @dev: ISHTP device instance * @cl: ISHTP client instance * * Send disconnect message to fw * * Return: 0 if success else error code */ int ishtp_hbm_cl_disconnect_req(struct ishtp_device *dev, struct ishtp_cl *cl) { … } /** * ishtp_hbm_cl_disconnect_res() - Get disconnect response * @dev: ISHTP device instance * @rs: Response message * * Received disconnect response from fw */ static void ishtp_hbm_cl_disconnect_res(struct ishtp_device *dev, struct hbm_client_connect_response *rs) { … } /** * ishtp_hbm_cl_connect_req() - Send connect request * @dev: ISHTP device instance * @cl: client device instance * * Send connection request to specific fw client * * Return: 0 if success else error code */ int ishtp_hbm_cl_connect_req(struct ishtp_device *dev, struct ishtp_cl *cl) { … } /** * ishtp_hbm_cl_connect_res() - Get connect response * @dev: ISHTP device instance * @rs: Response message * * Received connect response from fw */ static void ishtp_hbm_cl_connect_res(struct ishtp_device *dev, struct hbm_client_connect_response *rs) { … } /** * ishtp_hbm_fw_disconnect_req() - Receive disconnect request * @dev: ISHTP device instance * @disconnect_req: disconnect request structure * * Disconnect request bus message from the fw. Send disconnect response. */ static void ishtp_hbm_fw_disconnect_req(struct ishtp_device *dev, struct hbm_client_connect_request *disconnect_req) { … } /** * ishtp_hbm_dma_xfer_ack() - Receive transfer ACK * @dev: ISHTP device instance * @dma_xfer: HBM transfer message * * Receive ack for ISHTP-over-DMA client message */ static void ishtp_hbm_dma_xfer_ack(struct ishtp_device *dev, struct dma_xfer_hbm *dma_xfer) { … } /** * ishtp_hbm_dma_xfer() - Receive DMA transfer message * @dev: ISHTP device instance * @dma_xfer: HBM transfer message * * Receive ISHTP-over-DMA client message */ static void ishtp_hbm_dma_xfer(struct ishtp_device *dev, struct dma_xfer_hbm *dma_xfer) { … } /** * ishtp_hbm_dispatch() - HBM dispatch function * @dev: ISHTP device instance * @hdr: bus message * * Bottom half read routine after ISR to handle the read bus message cmd * processing */ void ishtp_hbm_dispatch(struct ishtp_device *dev, struct ishtp_bus_message *hdr) { … } /** * bh_hbm_work_fn() - HBM work function * @work: work struct * * Bottom half processing work function (instead of thread handler) * for processing hbm messages */ void bh_hbm_work_fn(struct work_struct *work) { … } /** * recv_hbm() - Receive HBM message * @dev: ISHTP device instance * @ishtp_hdr: received bus message * * Receive and process ISHTP bus messages in ISR context. This will schedule * work function to process message */ void recv_hbm(struct ishtp_device *dev, struct ishtp_msg_hdr *ishtp_hdr) { … } /** * ishtp_loader_recv_msg() - Receive a message from the ISHTP device * @dev: The ISHTP device * @buf: The buffer containing the message */ static void ishtp_loader_recv_msg(struct ishtp_device *dev, void *buf) { … } /** * recv_fixed_cl_msg() - Receive fixed client message * @dev: ISHTP device instance * @ishtp_hdr: received bus message * * Receive and process ISHTP fixed client messages (address == 0) * in ISR context */ void recv_fixed_cl_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *ishtp_hdr) { … } /** * fix_cl_hdr() - Initialize fixed client header * @hdr: message header * @length: length of message * @cl_addr: Client address * * Initialize message header for fixed client */ static inline void fix_cl_hdr(struct ishtp_msg_hdr *hdr, size_t length, uint8_t cl_addr) { … } /*** Suspend and resume notification ***/ static uint32_t current_state; static uint32_t supported_states = …; /** * ishtp_send_suspend() - Send suspend message to FW * @dev: ISHTP device instance * * Send suspend message to FW. This is useful for system freeze (non S3) case */ void ishtp_send_suspend(struct ishtp_device *dev) { … } EXPORT_SYMBOL(…); /** * ishtp_send_resume() - Send resume message to FW * @dev: ISHTP device instance * * Send resume message to FW. This is useful for system freeze (non S3) case */ void ishtp_send_resume(struct ishtp_device *dev) { … } EXPORT_SYMBOL(…); /** * ishtp_query_subscribers() - Send query subscribers message * @dev: ISHTP device instance * * Send message to query subscribers */ void ishtp_query_subscribers(struct ishtp_device *dev) { … }