summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorVictor Hsu <hsuvictor@google.com>2021-11-10 14:01:16 +0800
committerVictor Hsu <hsuvictor@google.com>2021-12-13 13:34:17 +0800
commitc972edc5cac0526943caaa390ddd0faf2ecb18db (patch)
tree653bbcbe5021b5cac251e2da2ac41583c6b0868d /inc
parent11b8045bbc3a20844fd6abeb460df31dcd70bbb4 (diff)
downloadcnss2-c972edc5cac0526943caaa390ddd0faf2ecb18db.tar.gz
wcn6740: Build mhi/qmi/qrtr out of kernel tree
Bug: 203725513 Signed-off-by: Victor Hsu <hsuvictor@google.com> Change-Id: Ie484ffaf1bde124d141e8e87adf9e3beb5cf7174
Diffstat (limited to 'inc')
-rw-r--r--inc/ipc_logging.h287
-rw-r--r--inc/mhi.h843
-rw-r--r--inc/mhi_misc.h562
-rw-r--r--inc/soc/qcom/qmi.h272
4 files changed, 1964 insertions, 0 deletions
diff --git a/inc/ipc_logging.h b/inc/ipc_logging.h
new file mode 100644
index 0000000..e60492f
--- /dev/null
+++ b/inc/ipc_logging.h
@@ -0,0 +1,287 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2012-2015,2017,2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _IPC_LOGGING_H
+#define _IPC_LOGGING_H
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+#define MAX_MSG_SIZE 255
+
+enum {
+ TSV_TYPE_MSG_START = 1,
+ TSV_TYPE_SKB = TSV_TYPE_MSG_START,
+ TSV_TYPE_STRING,
+ TSV_TYPE_MSG_END = TSV_TYPE_STRING,
+};
+
+struct tsv_header {
+ unsigned char type;
+ unsigned char size; /* size of data field */
+};
+
+struct encode_context {
+ struct tsv_header hdr;
+ char buff[MAX_MSG_SIZE];
+ int offset;
+};
+
+struct decode_context {
+ int output_format; /* 0 = debugfs */
+ char *buff; /* output buffer */
+ int size; /* size of output buffer */
+};
+
+#if IS_ENABLED(CONFIG_IPC_LOGGING)
+/*
+ * ipc_log_context_create: Create a debug log context
+ * Should not be called from atomic context
+ *
+ * @max_num_pages: Number of pages of logging space required (max. 10)
+ * @mod_name : Name of the directory entry under DEBUGFS
+ * @feature_version : First 16 bit for version number of user-defined message
+ * formats and next 16 bit for enabling minidump
+ *
+ * returns context id on success, NULL on failure
+ */
+void *ipc_log_context_create(int max_num_pages, const char *modname,
+ uint32_t feature_version);
+
+/*
+ * msg_encode_start: Start encoding a log message
+ *
+ * @ectxt: Temporary storage to hold the encoded message
+ * @type: Root event type defined by the module which is logging
+ */
+void msg_encode_start(struct encode_context *ectxt, uint32_t type);
+
+/*
+ * tsv_timestamp_write: Writes the current timestamp count
+ *
+ * @ectxt: Context initialized by calling msg_encode_start()
+ */
+int tsv_timestamp_write(struct encode_context *ectxt);
+
+/*
+ * tsv_qtimer_write: Writes the current QTimer timestamp count
+ *
+ * @ectxt: Context initialized by calling msg_encode_start()
+ */
+int tsv_qtimer_write(struct encode_context *ectxt);
+
+/*
+ * tsv_pointer_write: Writes a data pointer
+ *
+ * @ectxt: Context initialized by calling msg_encode_start()
+ * @pointer: Pointer value to write
+ */
+int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
+
+/*
+ * tsv_int32_write: Writes a 32-bit integer value
+ *
+ * @ectxt: Context initialized by calling msg_encode_start()
+ * @n: Integer to write
+ */
+int tsv_int32_write(struct encode_context *ectxt, int32_t n);
+
+/*
+ * tsv_byte_array_write: Writes a byte array
+ *
+ * @ectxt: Context initialized by calling msg_encode_start()
+ * @data: Pointer to byte array
+ * @data_size: Size of byte array
+ */
+int tsv_byte_array_write(struct encode_context *ectxt,
+ void *data, int data_size);
+
+/*
+ * msg_encode_end: Complete the message encode process
+ *
+ * @ectxt: Temporary storage which holds the encoded message
+ */
+void msg_encode_end(struct encode_context *ectxt);
+
+/*
+ * ipc_log_write: Commits message to logging ring buffer
+ *
+ * @ctxt: Logging context
+ * @ectxt: Temporary storage which holds the encoded message
+ */
+void ipc_log_write(void *ctxt, struct encode_context *ectxt);
+
+/*
+ * ipc_log_string: Helper function to log a string
+ *
+ * @ilctxt: Debug Log Context created using ipc_log_context_create()
+ * @fmt: Data specified using format specifiers
+ */
+int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
+
+/**
+ * ipc_log_extract - Reads and deserializes log
+ *
+ * @ilctxt: logging context
+ * @buff: buffer to receive the data
+ * @size: size of the buffer
+ * @returns: 0 if no data read; >0 number of bytes read; < 0 error
+ *
+ * If no data is available to be read, then the ilctxt::read_avail
+ * completion is reinitialized. This allows clients to block
+ * until new log data is save.
+ */
+int ipc_log_extract(void *ilctxt, char *buff, int size);
+
+/*
+ * Print a string to decode context.
+ * @dctxt Decode context
+ * @args printf args
+ */
+#define IPC_SPRINTF_DECODE(dctxt, args...) \
+do { \
+ int i; \
+ i = scnprintf(dctxt->buff, dctxt->size, args); \
+ dctxt->buff += i; \
+ dctxt->size -= i; \
+} while (0)
+
+/*
+ * tsv_timestamp_read: Reads a timestamp
+ *
+ * @ectxt: Context retrieved by reading from log space
+ * @dctxt: Temporary storage to hold the decoded message
+ * @format: Output format while dumping through DEBUGFS
+ */
+void tsv_timestamp_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format);
+
+/*
+ * tsv_qtimer_read: Reads a QTimer timestamp
+ *
+ * @ectxt: Context retrieved by reading from log space
+ * @dctxt: Temporary storage to hold the decoded message
+ * @format: Output format while dumping through DEBUGFS
+ */
+void tsv_qtimer_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format);
+
+/*
+ * tsv_pointer_read: Reads a data pointer
+ *
+ * @ectxt: Context retrieved by reading from log space
+ * @dctxt: Temporary storage to hold the decoded message
+ * @format: Output format while dumping through DEBUGFS
+ */
+void tsv_pointer_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format);
+
+/*
+ * tsv_int32_read: Reads a 32-bit integer value
+ *
+ * @ectxt: Context retrieved by reading from log space
+ * @dctxt: Temporary storage to hold the decoded message
+ * @format: Output format while dumping through DEBUGFS
+ */
+int32_t tsv_int32_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format);
+
+/*
+ * tsv_byte_array_read: Reads a byte array
+ *
+ * @ectxt: Context retrieved by reading from log space
+ * @dctxt: Temporary storage to hold the decoded message
+ * @format: Output format while dumping through DEBUGFS
+ */
+void tsv_byte_array_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format);
+
+/*
+ * add_deserialization_func: Register a deserialization function to
+ * to unpack the subevents of a main event
+ *
+ * @ctxt: Debug log context to which the deserialization function has
+ * to be registered
+ * @type: Main/Root event, defined by the module which is logging, to
+ * which this deserialization function has to be registered.
+ * @dfune: Deserialization function to be registered
+ *
+ * return 0 on success, -ve value on FAILURE
+ */
+int add_deserialization_func(void *ctxt, int type,
+ void (*dfunc)(struct encode_context *,
+ struct decode_context *));
+
+/*
+ * ipc_log_context_destroy: Destroy debug log context
+ *
+ * @ctxt: debug log context created by calling ipc_log_context_create API.
+ */
+int ipc_log_context_destroy(void *ctxt);
+
+#else
+
+static inline void *ipc_log_context_create(int max_num_pages,
+ const char *modname, uint32_t feature_version)
+{ return NULL; }
+
+static inline void msg_encode_start(struct encode_context *ectxt,
+ uint32_t type) { }
+
+static inline int tsv_timestamp_write(struct encode_context *ectxt)
+{ return -EINVAL; }
+
+static inline int tsv_qtimer_write(struct encode_context *ectxt)
+{ return -EINVAL; }
+
+static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
+{ return -EINVAL; }
+
+static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
+{ return -EINVAL; }
+
+static inline int tsv_byte_array_write(struct encode_context *ectxt,
+ void *data, int data_size)
+{ return -EINVAL; }
+
+static inline void msg_encode_end(struct encode_context *ectxt) { }
+
+static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
+
+static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
+{ return -EINVAL; }
+
+static inline int ipc_log_extract(void *ilctxt, char *buff, int size)
+{ return -EINVAL; }
+
+#define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
+
+static inline void tsv_timestamp_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format) { }
+
+static inline void tsv_qtimer_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format) { }
+
+static inline void tsv_pointer_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format) { }
+
+static inline int32_t tsv_int32_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format)
+{ return 0; }
+
+static inline void tsv_byte_array_read(struct encode_context *ectxt,
+ struct decode_context *dctxt, const char *format) { }
+
+static inline int add_deserialization_func(void *ctxt, int type,
+ void (*dfunc)(struct encode_context *,
+ struct decode_context *))
+{ return 0; }
+
+static inline int ipc_log_context_destroy(void *ctxt)
+{ return 0; }
+
+#endif
+
+#endif
diff --git a/inc/mhi.h b/inc/mhi.h
new file mode 100644
index 0000000..50e4935
--- /dev/null
+++ b/inc/mhi.h
@@ -0,0 +1,843 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ *
+ */
+#ifndef _MHI_H_
+#define _MHI_H_
+
+#include <linux/device.h>
+#include <linux/dma-direction.h>
+#include <linux/mutex.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+/* MHI client drivers to set this upper bound for tx buffer */
+#define MHI_MAX_MTU 0xffff
+
+#define MHI_MAX_OEM_PK_HASH_SEGMENTS 16
+
+struct mhi_chan;
+struct mhi_event;
+struct mhi_ctxt;
+struct mhi_cmd;
+struct mhi_buf_info;
+
+/**
+ * enum mhi_callback - MHI callback
+ * @MHI_CB_IDLE: MHI entered idle state
+ * @MHI_CB_PENDING_DATA: New data available for client to process
+ * @MHI_CB_LPM_ENTER: MHI host entered low power mode
+ * @MHI_CB_LPM_EXIT: MHI host about to exit low power mode
+ * @MHI_CB_EE_RDDM: MHI device entered RDDM exec env
+ * @MHI_CB_EE_MISSION_MODE: MHI device entered Mission Mode exec env
+ * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
+ * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
+ * @MHI_CB_BW_REQ: Received a bandwidth switch request from device
+ * @MHI_CB_FALLBACK_IMG: MHI device was loaded with the provided fallback image
+ * @MHI_CB_DTR_SIGNAL: DTR signaling update
+ */
+enum mhi_callback {
+ MHI_CB_IDLE,
+ MHI_CB_PENDING_DATA,
+ MHI_CB_LPM_ENTER,
+ MHI_CB_LPM_EXIT,
+ MHI_CB_EE_RDDM,
+ MHI_CB_EE_MISSION_MODE,
+ MHI_CB_SYS_ERROR,
+ MHI_CB_FATAL_ERROR,
+ MHI_CB_BW_REQ,
+ MHI_CB_FALLBACK_IMG,
+ MHI_CB_DTR_SIGNAL,
+};
+
+/**
+ * enum mhi_flags - Transfer flags
+ * @MHI_EOB: End of buffer for bulk transfer
+ * @MHI_EOT: End of transfer
+ * @MHI_CHAIN: Linked transfer
+ */
+enum mhi_flags {
+ MHI_EOB = BIT(0),
+ MHI_EOT = BIT(1),
+ MHI_CHAIN = BIT(2),
+};
+
+/**
+ * enum mhi_device_type - Device types
+ * @MHI_DEVICE_XFER: Handles data transfer
+ * @MHI_DEVICE_CONTROLLER: Control device
+ */
+enum mhi_device_type {
+ MHI_DEVICE_XFER,
+ MHI_DEVICE_CONTROLLER,
+};
+
+/**
+ * enum mhi_ch_type - Channel types
+ * @MHI_CH_TYPE_INVALID: Invalid channel type
+ * @MHI_CH_TYPE_OUTBOUND: Outbound channel to the device
+ * @MHI_CH_TYPE_INBOUND: Inbound channel from the device
+ * @MHI_CH_TYPE_INBOUND_COALESCED: Coalesced channel for the device to combine
+ * multiple packets and send them as a single
+ * large packet to reduce CPU consumption
+ */
+enum mhi_ch_type {
+ MHI_CH_TYPE_INVALID = 0,
+ MHI_CH_TYPE_OUTBOUND = DMA_TO_DEVICE,
+ MHI_CH_TYPE_INBOUND = DMA_FROM_DEVICE,
+ MHI_CH_TYPE_INBOUND_COALESCED = 3,
+};
+
+/**
+ * struct image_info - Firmware and RDDM table
+ * @mhi_buf: Buffer for firmware and RDDM table
+ * @entries: # of entries in table
+ */
+struct image_info {
+ struct mhi_buf *mhi_buf;
+ /* private: from internal.h */
+ struct bhi_vec_entry *bhi_vec;
+ /* public: */
+ u32 entries;
+};
+
+/**
+ * struct mhi_link_info - BW requirement
+ * target_link_speed - Link speed as defined by TLS bits in LinkControl reg
+ * target_link_width - Link width as defined by NLW bits in LinkStatus reg
+ * sequence_num - used by device to track bw requests sent to host
+ */
+struct mhi_link_info {
+ unsigned int target_link_speed;
+ unsigned int target_link_width;
+ int sequence_num;
+};
+
+/**
+ * enum mhi_ee_type - Execution environment types
+ * @MHI_EE_PBL: Primary Bootloader
+ * @MHI_EE_SBL: Secondary Bootloader
+ * @MHI_EE_AMSS: Modem, aka the primary runtime EE
+ * @MHI_EE_RDDM: Ram dump download mode
+ * @MHI_EE_WFW: WLAN firmware mode
+ * @MHI_EE_PTHRU: Passthrough
+ * @MHI_EE_EDL: Embedded downloader
+ */
+enum mhi_ee_type {
+ MHI_EE_PBL,
+ MHI_EE_SBL,
+ MHI_EE_AMSS,
+ MHI_EE_RDDM,
+ MHI_EE_WFW,
+ MHI_EE_PTHRU,
+ MHI_EE_EDL,
+ MHI_EE_MAX_SUPPORTED = MHI_EE_EDL,
+ MHI_EE_DISABLE_TRANSITION, /* local EE, not related to mhi spec */
+ MHI_EE_NOT_SUPPORTED,
+ MHI_EE_MAX,
+};
+
+/**
+ * enum mhi_state - MHI states
+ * @MHI_STATE_RESET: Reset state
+ * @MHI_STATE_READY: Ready state
+ * @MHI_STATE_M0: M0 state
+ * @MHI_STATE_M1: M1 state
+ * @MHI_STATE_M2: M2 state
+ * @MHI_STATE_M3: M3 state
+ * @MHI_STATE_M3_FAST: M3 Fast state
+ * @MHI_STATE_BHI: BHI state
+ * @MHI_STATE_SYS_ERR: System Error state
+ */
+enum mhi_state {
+ MHI_STATE_RESET = 0x0,
+ MHI_STATE_READY = 0x1,
+ MHI_STATE_M0 = 0x2,
+ MHI_STATE_M1 = 0x3,
+ MHI_STATE_M2 = 0x4,
+ MHI_STATE_M3 = 0x5,
+ MHI_STATE_M3_FAST = 0x6,
+ MHI_STATE_BHI = 0x7,
+ MHI_STATE_SYS_ERR = 0xFF,
+ MHI_STATE_MAX,
+};
+
+/**
+ * enum mhi_ch_ee_mask - Execution environment mask for channel
+ * @MHI_CH_EE_PBL: Allow channel to be used in PBL EE
+ * @MHI_CH_EE_SBL: Allow channel to be used in SBL EE
+ * @MHI_CH_EE_AMSS: Allow channel to be used in AMSS EE
+ * @MHI_CH_EE_RDDM: Allow channel to be used in RDDM EE
+ * @MHI_CH_EE_PTHRU: Allow channel to be used in PTHRU EE
+ * @MHI_CH_EE_WFW: Allow channel to be used in WFW EE
+ * @MHI_CH_EE_EDL: Allow channel to be used in EDL EE
+ */
+enum mhi_ch_ee_mask {
+ MHI_CH_EE_PBL = BIT(MHI_EE_PBL),
+ MHI_CH_EE_SBL = BIT(MHI_EE_SBL),
+ MHI_CH_EE_AMSS = BIT(MHI_EE_AMSS),
+ MHI_CH_EE_RDDM = BIT(MHI_EE_RDDM),
+ MHI_CH_EE_PTHRU = BIT(MHI_EE_PTHRU),
+ MHI_CH_EE_WFW = BIT(MHI_EE_WFW),
+ MHI_CH_EE_EDL = BIT(MHI_EE_EDL),
+};
+
+/**
+ * enum mhi_er_data_type - Event ring data types
+ * @MHI_ER_DATA: Only client data over this ring
+ * @MHI_ER_CTRL: MHI control data and client data
+ * @MHI_ER_BW_SCALE: MHI controller bandwidth scale functionality
+ * @MHI_ER_TIMESYNC: MHI controller time synchronization DB mode functionality
+ */
+enum mhi_er_data_type {
+ MHI_ER_DATA,
+ MHI_ER_CTRL,
+ MHI_ER_BW_SCALE,
+ MHI_ER_TIMESYNC,
+};
+
+/**
+ * enum mhi_er_priority - Event ring processing priority
+ * @MHI_ER_PRIORITY_DEFAULT_NOSLEEP: processed by tasklet
+ * @MHI_ER_PRIORITY_HI_NOSLEEP: processed by hi-priority tasklet
+ * @MHI_ER_PRIORITY_HI_SLEEP: processed by hi-priority wq
+ */
+enum mhi_er_priority {
+ MHI_ER_PRIORITY_DEFAULT_NOSLEEP,
+ MHI_ER_PRIORITY_HI_NOSLEEP,
+ MHI_ER_PRIORITY_HI_SLEEP,
+};
+
+/**
+ * enum mhi_db_brst_mode - Doorbell mode
+ * @MHI_DB_BRST_DISABLE: Burst mode disable
+ * @MHI_DB_BRST_ENABLE: Burst mode enable
+ */
+enum mhi_db_brst_mode {
+ MHI_DB_BRST_DISABLE = 0x2,
+ MHI_DB_BRST_ENABLE = 0x3,
+};
+
+/**
+ * struct mhi_channel_config - Channel configuration structure for controller
+ * @name: The name of this channel
+ * @num: The number assigned to this channel
+ * @num_elements: The number of elements that can be queued to this channel
+ * @local_elements: The local ring length of the channel
+ * @event_ring: The event rung index that services this channel
+ * @dir: Direction that data may flow on this channel
+ * @type: Channel type
+ * @ee_mask: Execution Environment mask for this channel
+ * @pollcfg: Polling configuration for burst mode. 0 is default. milliseconds
+ for UL channels, multiple of 8 ring elements for DL channels
+ * @doorbell: Doorbell mode
+ * @lpm_notify: The channel master requires low power mode notifications
+ * @offload_channel: The client manages the channel completely
+ * @doorbell_mode_switch: Channel switches to doorbell mode on M0 transition
+ * @auto_queue: Framework will automatically queue buffers for DL traffic
+ * @wake-capable: Channel capable of waking up the system
+ */
+struct mhi_channel_config {
+ char *name;
+ u32 num;
+ u32 num_elements;
+ u32 local_elements;
+ u32 event_ring;
+ enum dma_data_direction dir;
+ enum mhi_ch_type type;
+ u32 ee_mask;
+ u32 pollcfg;
+ enum mhi_db_brst_mode doorbell;
+ bool lpm_notify;
+ bool offload_channel;
+ bool doorbell_mode_switch;
+ bool auto_queue;
+ bool wake_capable;
+};
+
+/**
+ * struct mhi_event_config - Event ring configuration structure for controller
+ * @num_elements: The number of elements that can be queued to this ring
+ * @irq_moderation_ms: Delay irq for additional events to be aggregated
+ * @irq: IRQ associated with this ring
+ * @channel: Dedicated channel number. U32_MAX indicates a non-dedicated ring
+ * @priority: Processing priority of this ring.
+ * @mode: Doorbell mode
+ * @data_type: Type of data this ring will process
+ * @hardware_event: This ring is associated with hardware channels
+ * @client_managed: This ring is client managed
+ * @offload_channel: This ring is associated with an offloaded channel
+ */
+struct mhi_event_config {
+ u32 num_elements;
+ u32 irq_moderation_ms;
+ u32 irq;
+ u32 channel;
+ u32 priority;
+ enum mhi_db_brst_mode mode;
+ enum mhi_er_data_type data_type;
+ bool hardware_event;
+ bool client_managed;
+ bool offload_channel;
+};
+
+/**
+ * struct mhi_controller_config - Root MHI controller configuration
+ * @max_channels: Maximum number of channels supported
+ * @timeout_ms: Timeout value for operations. 0 means use default
+ * @buf_len: Size of automatically allocated buffers. 0 means use default
+ * @num_channels: Number of channels defined in @ch_cfg
+ * @ch_cfg: Array of defined channels
+ * @num_events: Number of event rings defined in @event_cfg
+ * @event_cfg: Array of defined event rings
+ * @use_bounce_buf: Use a bounce buffer pool due to limited DDR access
+ * @m2_no_db: Host is not allowed to ring DB in M2 state
+ */
+struct mhi_controller_config {
+ u32 max_channels;
+ u32 timeout_ms;
+ u32 buf_len;
+ u32 num_channels;
+ const struct mhi_channel_config *ch_cfg;
+ u32 num_events;
+ const struct mhi_event_config *event_cfg;
+ bool use_bounce_buf;
+ bool m2_no_db;
+};
+
+/**
+ * struct mhi_controller - Master MHI controller structure
+ * @cntrl_dev: Pointer to the struct device of physical bus acting as the MHI
+ * controller (required)
+ * @mhi_dev: MHI device instance for the controller
+ * @debugfs_dentry: MHI controller debugfs directory
+ * @regs: Base address of MHI MMIO register space (required)
+ * @reg_len: Length of the MHI MMIO region (required)
+ * @bhi: Points to base of MHI BHI register space
+ * @bhie: Points to base of MHI BHIe register space
+ * @wake_db: MHI WAKE doorbell register address
+ * @iova_start: IOMMU starting address for data (required)
+ * @iova_stop: IOMMU stop address for data (required)
+ * @fw_image: Firmware image name for normal booting (required)
+ * @fallback_fw_image: Fallback firmware image name for backup boot (optional)
+ * @edl_image: Firmware image name for emergency download mode (optional)
+ * @rddm_size: RAM dump size that host should allocate for debugging purpose
+ * @sbl_size: SBL image size downloaded through BHIe (optional)
+ * @seg_len: BHIe vector size (optional)
+ * @fbc_image: Points to firmware image buffer
+ * @rddm_image: Points to RAM dump buffer
+ * @mhi_chan: Points to the channel configuration table
+ * @lpm_chans: List of channels that require LPM notifications
+ * @irq: base irq # to request (required)
+ * @max_chan: Maximum number of channels the controller supports
+ * @total_ev_rings: Total # of event rings allocated
+ * @hw_ev_rings: Number of hardware event rings
+ * @sw_ev_rings: Number of software event rings
+ * @nr_irqs: Number of IRQ allocated by bus master (required)
+ * @family_number: MHI controller family number
+ * @device_number: MHI controller device number
+ * @major_version: MHI controller major revision number
+ * @minor_version: MHI controller minor revision number
+ * @serial_number: MHI controller serial number obtained from BHI
+ * @oem_pk_hash: MHI controller OEM PK Hash obtained from BHI
+ * @mhi_event: MHI event ring configurations table
+ * @mhi_cmd: MHI command ring configurations table
+ * @mhi_ctxt: MHI device context, shared memory between host and device
+ * @pm_mutex: Mutex for suspend/resume operation
+ * @pm_lock: Lock for protecting MHI power management state
+ * @timeout_ms: Timeout in ms for state transitions
+ * @pm_state: MHI power management state
+ * @db_access: DB access states
+ * @ee: MHI device execution environment
+ * @dev_state: MHI device state
+ * @dev_wake: Device wakeup count
+ * @pending_pkts: Pending packets for the controller
+ * @M0, M2, M3, M3_fast: Counters to track number of device MHI state changes
+ * @transition_list: List of MHI state transitions
+ * @transition_lock: Lock for protecting MHI state transition list
+ * @wlock: Lock for protecting device wakeup
+ * @mhi_link_info: Device bandwidth info
+ * @st_worker: State transition worker
+ * @hiprio_wq: High priority workqueue for MHI work such as state transitions
+ * @state_event: State change event
+ * @status_cb: CB function to notify power states of the device (required)
+ * @wake_get: CB function to assert device wake (optional)
+ * @wake_put: CB function to de-assert device wake (optional)
+ * @wake_toggle: CB function to assert and de-assert device wake (optional)
+ * @runtime_get: CB function to controller runtime resume (required)
+ * @runtime_put: CB function to decrement pm usage (required)
+ * @map_single: CB function to create TRE buffer
+ * @unmap_single: CB function to destroy TRE buffer
+ * @read_reg: Read a MHI register via the physical link (required)
+ * @write_reg: Write a MHI register via the physical link (required)
+ * @reset: Controller specific reset function (optional)
+ * @buffer_len: Bounce buffer length
+ * @index: Index of the MHI controller instance
+ * @img_pre_alloc: allocate rddm and fbc image buffers one time
+ * @bounce_buf: Use of bounce buffer
+ * @fbc_download: MHI host needs to do complete image transfer (optional)
+ * @wake_set: Device wakeup set flag
+ *
+ * Fields marked as (required) need to be populated by the controller driver
+ * before calling mhi_register_controller(). For the fields marked as (optional)
+ * they can be populated depending on the usecase.
+ *
+ * The following fields are present for the purpose of implementing any device
+ * specific quirks or customizations for specific MHI revisions used in device
+ * by the controller drivers. The MHI stack will just populate these fields
+ * during mhi_register_controller():
+ * family_number
+ * device_number
+ * major_version
+ * minor_version
+ */
+struct mhi_controller {
+ struct device *cntrl_dev;
+ struct mhi_device *mhi_dev;
+ struct dentry *debugfs_dentry;
+ void __iomem *regs;
+ size_t reg_len;
+ void __iomem *bhi;
+ void __iomem *bhie;
+ void __iomem *wake_db;
+
+ dma_addr_t iova_start;
+ dma_addr_t iova_stop;
+ const char *fw_image;
+ const char *fallback_fw_image;
+ const char *edl_image;
+ size_t rddm_size;
+ size_t sbl_size;
+ size_t seg_len;
+ struct image_info *fbc_image;
+ struct image_info *rddm_image;
+ struct mhi_chan *mhi_chan;
+ struct list_head lpm_chans;
+ int *irq;
+ u32 max_chan;
+ u32 total_ev_rings;
+ u32 hw_ev_rings;
+ u32 sw_ev_rings;
+ u32 nr_irqs;
+ u32 family_number;
+ u32 device_number;
+ u32 major_version;
+ u32 minor_version;
+ u32 serial_number;
+ u32 oem_pk_hash[MHI_MAX_OEM_PK_HASH_SEGMENTS];
+ u32 session_id;
+
+ struct mhi_event *mhi_event;
+ struct mhi_cmd *mhi_cmd;
+ struct mhi_ctxt *mhi_ctxt;
+
+ struct mutex pm_mutex;
+ rwlock_t pm_lock;
+ u32 timeout_ms;
+ u32 pm_state;
+ u32 db_access;
+ enum mhi_ee_type ee;
+ enum mhi_state dev_state;
+ atomic_t dev_wake;
+ atomic_t pending_pkts;
+ u32 M0, M2, M3, M3_fast;
+ struct list_head transition_list;
+ spinlock_t transition_lock;
+ spinlock_t wlock;
+ struct mhi_link_info mhi_link_info;
+ struct work_struct st_worker;
+ struct workqueue_struct *hiprio_wq;
+ wait_queue_head_t state_event;
+
+ void (*status_cb)(struct mhi_controller *mhi_cntrl,
+ enum mhi_callback cb);
+ void (*wake_get)(struct mhi_controller *mhi_cntrl, bool override);
+ void (*wake_put)(struct mhi_controller *mhi_cntrl, bool override);
+ void (*wake_toggle)(struct mhi_controller *mhi_cntrl);
+ int (*runtime_get)(struct mhi_controller *mhi_cntrl);
+ void (*runtime_put)(struct mhi_controller *mhi_cntrl);
+ int (*map_single)(struct mhi_controller *mhi_cntrl,
+ struct mhi_buf_info *buf);
+ void (*unmap_single)(struct mhi_controller *mhi_cntrl,
+ struct mhi_buf_info *buf);
+ int (*read_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr,
+ u32 *out);
+ void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr,
+ u32 val);
+ void (*reset)(struct mhi_controller *mhi_cntrl);
+
+ size_t buffer_len;
+ int index;
+ bool img_pre_alloc;
+ bool bounce_buf;
+ bool fbc_download;
+ bool wake_set;
+};
+
+/**
+ * struct mhi_device - Structure representing an MHI device which binds
+ * to channels or is associated with controllers
+ * @id: Pointer to MHI device ID struct
+ * @name: Name of the associated MHI device
+ * @mhi_cntrl: Controller the device belongs to
+ * @ul_chan: UL channel for the device
+ * @dl_chan: DL channel for the device
+ * @dev: Driver model device node for the MHI device
+ * @dev_type: MHI device type
+ * @ul_chan_id: MHI channel id for UL transfer
+ * @ul_event_id: MHI event ring id for UL transfer
+ * @dl_chan_id: MHI channel id for DL transfer
+ * @ul_event_id: MHI event ring id for DL transfer
+ * @dev_wake: Device wakeup counter
+ * @tiocm: Device current terminal settings
+ */
+struct mhi_device {
+ const struct mhi_device_id *id;
+ const char *name;
+ struct mhi_controller *mhi_cntrl;
+ struct mhi_chan *ul_chan;
+ struct mhi_chan *dl_chan;
+ struct device dev;
+ enum mhi_device_type dev_type;
+ int ul_chan_id;
+ int ul_event_id;
+ int dl_chan_id;
+ int dl_event_id;
+ u32 dev_wake;
+ u32 tiocm;
+};
+
+/**
+ * struct mhi_result - Completed buffer information
+ * @buf_addr: Address of data buffer
+ * @bytes_xferd: # of bytes transferred
+ * @dir: Channel direction
+ * @transaction_status: Status of last transaction
+ */
+struct mhi_result {
+ void *buf_addr;
+ size_t bytes_xferd;
+ enum dma_data_direction dir;
+ int transaction_status;
+};
+
+/**
+ * struct mhi_buf - MHI Buffer description
+ * @buf: Virtual address of the buffer
+ * @name: Buffer label. For offload channel, configurations name must be:
+ * ECA - Event context array data
+ * CCA - Channel context array data
+ * @dma_addr: IOMMU address of the buffer
+ * @len: # of bytes
+ */
+struct mhi_buf {
+ void *buf;
+ const char *name;
+ dma_addr_t dma_addr;
+ size_t len;
+};
+
+/**
+ * struct mhi_driver - Structure representing a MHI client driver
+ * @probe: CB function for client driver probe function
+ * @remove: CB function for client driver remove function
+ * @ul_xfer_cb: CB function for UL data transfer
+ * @dl_xfer_cb: CB function for DL data transfer
+ * @status_cb: CB functions for asynchronous status
+ * @driver: Device driver model driver
+ */
+struct mhi_driver {
+ const struct mhi_device_id *id_table;
+ int (*probe)(struct mhi_device *mhi_dev,
+ const struct mhi_device_id *id);
+ void (*remove)(struct mhi_device *mhi_dev);
+ void (*ul_xfer_cb)(struct mhi_device *mhi_dev,
+ struct mhi_result *result);
+ void (*dl_xfer_cb)(struct mhi_device *mhi_dev,
+ struct mhi_result *result);
+ void (*status_cb)(struct mhi_device *mhi_dev, enum mhi_callback mhi_cb);
+ struct device_driver driver;
+};
+
+#define to_mhi_driver(drv) container_of(drv, struct mhi_driver, driver)
+#define to_mhi_device(dev) container_of(dev, struct mhi_device, dev)
+
+/**
+ * mhi_alloc_controller - Allocate the MHI Controller structure
+ * Allocate the mhi_controller structure using zero initialized memory
+ */
+struct mhi_controller *mhi_alloc_controller(void);
+
+/**
+ * mhi_free_controller - Free the MHI Controller structure
+ * Free the mhi_controller structure which was previously allocated
+ */
+void mhi_free_controller(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_register_controller - Register MHI controller
+ * @mhi_cntrl: MHI controller to register
+ * @config: Configuration to use for the controller
+ */
+int mhi_register_controller(struct mhi_controller *mhi_cntrl,
+ const struct mhi_controller_config *config);
+
+/**
+ * mhi_unregister_controller - Unregister MHI controller
+ * @mhi_cntrl: MHI controller to unregister
+ */
+void mhi_unregister_controller(struct mhi_controller *mhi_cntrl);
+
+/*
+ * module_mhi_driver() - Helper macro for drivers that don't do
+ * anything special other than using default mhi_driver_register() and
+ * mhi_driver_unregister(). This eliminates a lot of boilerplate.
+ * Each module may only use this macro once.
+ */
+#define module_mhi_driver(mhi_drv) \
+ module_driver(mhi_drv, mhi_driver_register, \
+ mhi_driver_unregister)
+
+/*
+ * Macro to avoid include chaining to get THIS_MODULE
+ */
+#define mhi_driver_register(mhi_drv) \
+ __mhi_driver_register(mhi_drv, THIS_MODULE)
+
+/**
+ * __mhi_driver_register - Register driver with MHI framework
+ * @mhi_drv: Driver associated with the device
+ * @owner: The module owner
+ */
+int __mhi_driver_register(struct mhi_driver *mhi_drv, struct module *owner);
+
+/**
+ * mhi_driver_unregister - Unregister a driver for mhi_devices
+ * @mhi_drv: Driver associated with the device
+ */
+void mhi_driver_unregister(struct mhi_driver *mhi_drv);
+
+/**
+ * mhi_set_mhi_state - Set MHI device state
+ * @mhi_cntrl: MHI controller
+ * @state: State to set
+ */
+void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl,
+ enum mhi_state state);
+
+/**
+ * mhi_notify - Notify the MHI client driver about client device status
+ * @mhi_dev: MHI device instance
+ * @cb_reason: MHI callback reason
+ */
+void mhi_notify(struct mhi_device *mhi_dev, enum mhi_callback cb_reason);
+
+/**
+ * mhi_get_free_desc_count - Get transfer ring length
+ * Get # of TD available to queue buffers
+ * @mhi_dev: Device associated with the channels
+ * @dir: Direction of the channel
+ */
+int mhi_get_free_desc_count(struct mhi_device *mhi_dev,
+ enum dma_data_direction dir);
+
+/**
+ * mhi_prepare_for_power_up - Do pre-initialization before power up.
+ * This is optional, call this before power up if
+ * the controller does not want bus framework to
+ * automatically free any allocated memory during
+ * shutdown process.
+ * @mhi_cntrl: MHI controller
+ */
+int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_async_power_up - Start MHI power up sequence
+ * @mhi_cntrl: MHI controller
+ */
+int mhi_async_power_up(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_sync_power_up - Start MHI power up sequence and wait till the device
+ * enters valid EE state
+ * @mhi_cntrl: MHI controller
+ */
+int mhi_sync_power_up(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_power_down - Start MHI power down sequence
+ * @mhi_cntrl: MHI controller
+ * @graceful: Link is still accessible, so do a graceful shutdown process
+ */
+void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful);
+
+/**
+ * mhi_unprepare_after_power_down - Free any allocated memory after power down
+ * @mhi_cntrl: MHI controller
+ */
+void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_pm_suspend - Move MHI into a suspended state
+ * @mhi_cntrl: MHI controller
+ */
+int mhi_pm_suspend(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_pm_resume - Resume MHI from suspended state
+ * @mhi_cntrl: MHI controller
+ */
+int mhi_pm_resume(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_download_rddm_image - Download ramdump image from device for
+ * debugging purpose.
+ * @mhi_cntrl: MHI controller
+ * @in_panic: Download rddm image during kernel panic
+ */
+int mhi_download_rddm_image(struct mhi_controller *mhi_cntrl, bool in_panic);
+
+/**
+ * mhi_force_rddm_mode - Force device into rddm mode
+ * @mhi_cntrl: MHI controller
+ */
+int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_get_exec_env - Get BHI execution environment of the device
+ * @mhi_cntrl: MHI controller
+ */
+enum mhi_ee_type mhi_get_exec_env(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_get_mhi_state - Get MHI state of the device
+ * @mhi_cntrl: MHI controller
+ */
+enum mhi_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_soc_reset - Trigger a device reset. This can be used as a last resort
+ * to reset and recover a device.
+ * @mhi_cntrl: MHI controller
+ */
+void mhi_soc_reset(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_device_get - Disable device low power mode
+ * @mhi_dev: Device associated with the channel
+ */
+void mhi_device_get(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_device_get_sync - Disable device low power mode. Synchronously
+ * take the controller out of suspended state
+ * @mhi_dev: Device associated with the channel
+ */
+int mhi_device_get_sync(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_device_put - Re-enable device low power mode
+ * @mhi_dev: Device associated with the channel
+ */
+void mhi_device_put(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_prepare_for_transfer - Setup UL and DL channels for data transfer.
+ * Allocate and initialize the channel context and
+ * also issue the START channel command to both
+ * channels. Channels can be started only if both
+ * host and device execution environments match and
+ * channels are in a DISABLED state. Calling the
+ * mhi_start_transfer() function is not required
+ * afterwards as channels are already started. This
+ * function also initializes the channel context
+ * whereas mhi_start_transfer() can only be used to
+ * issue the start channel command once the context
+ * is setup.
+ * @mhi_dev: Device associated with the channels
+ */
+int mhi_prepare_for_transfer(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_unprepare_from_transfer - Reset UL and DL channels for data transfer.
+ * Issue the RESET channel command and let the
+ * device clean-up the context so no incoming
+ * transfers are seen on the host. Free memory
+ * associated with the context on host. If device
+ * is unresponsive, only perform a host side
+ * clean-up. Channels can be reset only if both
+ * host and device execution environments match
+ * and channels are in an ENABLED, STOPPED or
+ * SUSPENDED state. Calling mhi_stop_transfer() is
+ * not required before calling this function as it
+ * will only stop transfers, not reset channels.
+ * @mhi_dev: Device associated with the channels
+ */
+void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_stop_transfer - Pauses ongoing channel activity by issuing the STOP
+ * channel command to both UL and DL channels. This command
+ * does not reset the channel context and the client drivers
+ * can issue mhi_start_transfer to resume activity.
+ * @mhi_dev: Device associated with the channels
+ */
+int mhi_stop_transfer(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_start_transfer - Resumes channel activity by issuing the START channel
+ * command to both UL and DL channels. This command assumes
+ * the channel context is already setup and the client
+ * drivers can issue mhi_stop_transfer to pause activity if
+ * required.
+ * @mhi_dev: Device associated with the channels
+ */
+int mhi_start_transfer(struct mhi_device *mhi_dev);
+
+/**
+ * mhi_poll - Poll for any available data in DL direction
+ * @mhi_dev: Device associated with the channels
+ * @budget: # of events to process
+ */
+int mhi_poll(struct mhi_device *mhi_dev, u32 budget);
+
+/**
+ * mhi_queue_dma - Send or receive DMA mapped buffers from client device
+ * over MHI channel
+ * @mhi_dev: Device associated with the channels
+ * @dir: DMA direction for the channel
+ * @mhi_buf: Buffer for holding the DMA mapped data
+ * @len: Buffer length
+ * @mflags: MHI transfer flags used for the transfer
+ */
+int mhi_queue_dma(struct mhi_device *mhi_dev, enum dma_data_direction dir,
+ struct mhi_buf *mhi_buf, size_t len, enum mhi_flags mflags);
+
+/**
+ * mhi_queue_buf - Send or receive raw buffers from client device over MHI
+ * channel
+ * @mhi_dev: Device associated with the channels
+ * @dir: DMA direction for the channel
+ * @buf: Buffer for holding the data
+ * @len: Buffer length
+ * @mflags: MHI transfer flags used for the transfer
+ */
+int mhi_queue_buf(struct mhi_device *mhi_dev, enum dma_data_direction dir,
+ void *buf, size_t len, enum mhi_flags mflags);
+
+/**
+ * mhi_queue_skb - Send or receive SKBs from client device over MHI channel
+ * @mhi_dev: Device associated with the channels
+ * @dir: DMA direction for the channel
+ * @skb: Buffer for holding SKBs
+ * @len: Buffer length
+ * @mflags: MHI transfer flags used for the transfer
+ */
+int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir,
+ struct sk_buff *skb, size_t len, enum mhi_flags mflags);
+
+#endif /* _MHI_H_ */
diff --git a/inc/mhi_misc.h b/inc/mhi_misc.h
new file mode 100644
index 0000000..b8ff0ff
--- /dev/null
+++ b/inc/mhi_misc.h
@@ -0,0 +1,562 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#ifndef _MHI_MISC_H_
+#define _MHI_MISC_H_
+
+#include <linux/mhi.h>
+#include <linux/ipc_logging.h>
+
+/**
+ * enum MHI_DEBUG_LEVEL - various debugging levels
+ */
+enum MHI_DEBUG_LEVEL {
+ MHI_MSG_LVL_VERBOSE,
+ MHI_MSG_LVL_INFO,
+ MHI_MSG_LVL_ERROR,
+ MHI_MSG_LVL_CRITICAL,
+ MHI_MSG_LVL_MASK_ALL,
+ MHI_MSG_LVL_MAX,
+};
+
+#ifdef CONFIG_MHI_BUS_MISC
+
+/**
+ * mhi_report_error - Can be used by controller to signal error condition to the
+ * MHI core driver in case of any need to halt processing or incoming sideband
+ * signal detects an error on endpoint
+ * @mhi_cntrl: MHI controller
+ *
+ * Returns:
+ * 0 if success in reporting the error condition to MHI core
+ * error code on failure
+ */
+int mhi_report_error(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_controller_set_privdata - Set private data for MHI controller
+ * @mhi_cntrl: MHI controller
+ * @priv: pointer to data
+ */
+void mhi_controller_set_privdata(struct mhi_controller *mhi_cntrl, void *priv);
+
+/**
+ * mhi_controller_get_privdata - Get private data from MHI controller
+ * @mhi_cntrl: MHI controller
+ */
+void *mhi_controller_get_privdata(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_bdf_to_controller - Get controller associated with given BDF values
+ * @domain: Domain or root complex of PCIe port
+ * @bus: Bus number
+ * @slot: PCI slot or function number
+ * @dev_id: Device ID of the endpoint
+ *
+ * Returns:
+ * MHI controller structure pointer if BDF match is found
+ * NULL if cookie is not found
+ */
+struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id);
+
+/**
+ * mhi_set_m2_timeout_ms - Set M2 timeout in milliseconds to wait before a
+ * fast/silent suspend
+ * @mhi_cntrl: MHI controller
+ * @timeout: timeout in ms
+ */
+void mhi_set_m2_timeout_ms(struct mhi_controller *mhi_cntrl, u32 timeout);
+
+/**
+ * mhi_pm_fast_resume - Resume MHI from a fast/silent suspended state
+ * @mhi_cntrl: MHI controller
+ * @notify_clients: if true, clients will be notified of the resume transition
+ */
+int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_clients);
+
+/**
+ * mhi_pm_fast_suspend - Move MHI into a fast/silent suspended state
+ * @mhi_cntrl: MHI controller
+ * @notify_clients: if true, clients will be notified of the suspend transition
+ */
+int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_clients);
+
+/**
+ * mhi_debug_reg_dump - dump MHI registers for debug purpose
+ * @mhi_cntrl: MHI controller
+ */
+void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_dump_sfr - Print SFR string from RDDM table.
+ * @mhi_cntrl: MHI controller
+ */
+void mhi_dump_sfr(struct mhi_controller *mhi_cntrl);
+
+/**
+ * mhi_device_configure - Allow devices with offload channels to setup their own
+ * channel and event ring context.
+ * @mhi_dev: MHI device
+ * @dir: direction associated with the channel needed to configure
+ * @cfg_tbl: Buffer with ECA/CCA information and data needed to setup context
+ * @elements: Number of items to iterate over from the configuration table
+ */
+int mhi_device_configure(struct mhi_device *mhi_dev,
+ enum dma_data_direction dir,
+ struct mhi_buf *cfg_tbl,
+ int elements);
+
+/**
+ * mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
+ * registers set by device to indicate rddm readiness for debugging purposes.
+ * @mhi_cntrl: MHI controller
+ * @cookie: cookie/pattern value to match
+ *
+ * Returns:
+ * true if cookie is found
+ * false if cookie is not found
+ */
+bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie);
+
+/**
+ * mhi_device_get_sync_atomic - Asserts device_wait and moves device to M0
+ * @mhi_dev: Device associated with the channels
+ * @timeout_us: timeout, in micro-seconds
+ * @in_panic: If requested while kernel is in panic state and no ISRs expected
+ *
+ * The device_wake is asserted to keep device in M0 or bring it to M0.
+ * If device is not in M0 state, then this function will wait for device to
+ * move to M0, until @timeout_us elapses.
+ * However, if device's M1 state-change event races with this function
+ * then there is a possiblity of device moving from M0 to M2 and back
+ * to M0. That can't be avoided as host must transition device from M1 to M2
+ * as per the spec.
+ * Clients can ignore that transition after this function returns as the device
+ * is expected to immediately move from M2 to M0 as wake is asserted and
+ * wouldn't enter low power state.
+ * If in_panic boolean is set, no ISRs are expected, hence this API will have to
+ * resort to reading the MHI status register and poll on M0 state change.
+ *
+ * Returns:
+ * 0 if operation was successful (however, M0 -> M2 -> M0 is possible later) as
+ * mentioned above.
+ * -ETIMEDOUT is device faled to move to M0 before @timeout_us elapsed
+ * -EIO if the MHI state is one of the ERROR states.
+ */
+int mhi_device_get_sync_atomic(struct mhi_device *mhi_dev, int timeout_us,
+ bool in_panic);
+
+/**
+ * mhi_controller_set_bw_scale_cb - Set the BW scale callback for MHI controller
+ * @mhi_cntrl: MHI controller
+ * @cb_func: Callback to set for the MHI controller to receive BW scale requests
+ */
+void mhi_controller_set_bw_scale_cb(struct mhi_controller *mhi_cntrl,
+ int (*cb_func)(struct mhi_controller *mhi_cntrl,
+ struct mhi_link_info *link_info));
+/**
+ * mhi_controller_set_base - Set the controller base / resource start address
+ * @mhi_cntrl: MHI controller
+ * @base: Physical address to be set for future reference
+ */
+void mhi_controller_set_base(struct mhi_controller *mhi_cntrl,
+ phys_addr_t base);
+
+/**
+ * mhi_get_channel_db_base - retrieve the channel doorbell base address
+ * @mhi_dev: Device associated with the channels
+ * @value: Pointer to an address value which will be populated
+ */
+int mhi_get_channel_db_base(struct mhi_device *mhi_dev, phys_addr_t *value);
+
+/**
+ * mhi_get_event_ring_db_base - retrieve the event ring doorbell base address
+ * @mhi_dev: Device associated with the channels
+ * @value: Pointer to an address value which will be populated
+ */
+int mhi_get_event_ring_db_base(struct mhi_device *mhi_dev, phys_addr_t *value);
+
+/**
+ * mhi_get_device_for_channel - get the MHI device for a specific channel number
+ * @mhi_cntrl: MHI controller
+ * @channel - channel number
+ *
+ * Returns:
+ * Pointer to the MHI device associated with the channel
+ */
+struct mhi_device *mhi_get_device_for_channel(struct mhi_controller *mhi_cntrl,
+ u32 channel);
+
+/**
+ * mhi_device_ioctl - user space IOCTL support for MHI channels
+ * Native support for setting TIOCM
+ * @mhi_dev: Device associated with the channels
+ * @cmd: IOCTL cmd
+ * @arg: Optional parameter, iotcl cmd specific
+ */
+long mhi_device_ioctl(struct mhi_device *mhi_dev, unsigned int cmd,
+ unsigned long arg);
+
+/**
+ * mhi_controller_set_sfr_support - Set support for subsystem failure reason
+ * @mhi_cntrl: MHI controller
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_controller_set_sfr_support(struct mhi_controller *mhi_cntrl,
+ size_t len);
+
+/**
+ * mhi_controller_setup_timesync - Set support for time synchronization feature
+ * @mhi_cntrl: MHI controller
+ * @time_get: Callback to set for the MHI controller to receive host time
+ * @lpm_disable: Callback to set for the MHI controller to disable link LPM
+ * @lpm_enable: Callback to set for the MHI controller to enable link LPM
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_controller_setup_timesync(struct mhi_controller *mhi_cntrl,
+ u64 (*time_get)(struct mhi_controller *c),
+ int (*lpm_disable)(struct mhi_controller *c),
+ int (*lpm_enable)(struct mhi_controller *c));
+
+/**
+ * mhi_get_remote_time_sync - Get external soc time relative to local soc time
+ * using MMIO method.
+ * @mhi_dev: Device associated with the channels
+ * @t_host: Pointer to output local soc time
+ * @t_dev: Pointer to output remote soc time
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
+ u64 *t_host,
+ u64 *t_dev);
+
+/**
+ * mhi_get_remote_time - Get external modem time relative to host time
+ * Trigger event to capture modem time, also capture host time so client
+ * can do a relative drift comparision.
+ * Recommended only tsync device calls this method and do not call this
+ * from atomic context
+ * @mhi_dev: Device associated with the channels
+ * @sequence:unique sequence id track event
+ * @cb_func: callback function to call back
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_get_remote_time(struct mhi_device *mhi_dev,
+ u32 sequence,
+ void (*cb_func)(struct mhi_device *mhi_dev,
+ u32 sequence,
+ u64 local_time,
+ u64 remote_time));
+
+#else
+
+/**
+ * mhi_report_error - Can be used by controller to signal error condition to the
+ * MHI core driver in case of any need to halt processing or incoming sideband
+ * signal detects an error on endpoint
+ * @mhi_cntrl: MHI controller
+ *
+ * Returns:
+ * 0 if success in reporting the error condition to MHI core
+ * error code on failure
+ */
+static inline int mhi_report_error(struct mhi_controller *mhi_cntrl)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_controller_set_privdata - Set private data for MHI controller
+ * @mhi_cntrl: MHI controller
+ * @priv: pointer to data
+ */
+void mhi_controller_set_privdata(struct mhi_controller *mhi_cntrl, void *priv)
+{
+}
+
+/**
+ * mhi_controller_get_privdata - Get private data from MHI controller
+ * @mhi_cntrl: MHI controller
+ */
+void *mhi_controller_get_privdata(struct mhi_controller *mhi_cntrl)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+/**
+ * mhi_bdf_to_controller - Get controller associated with given BDF values
+ * @domain: Domain or root complex of PCIe port
+ * @bus: Bus number
+ * @slot: PCI slot or function number
+ * @dev_id: Device ID of the endpoint
+ *
+ * Returns:
+ * MHI controller structure pointer if BDF match is found
+ * NULL if cookie is not found
+ */
+struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+/**
+ * mhi_set_m2_timeout_ms - Set M2 timeout in milliseconds to wait before a
+ * fast/silent suspend
+ * @mhi_cntrl: MHI controller
+ * @timeout: timeout in ms
+ */
+void mhi_set_m2_timeout_ms(struct mhi_controller *mhi_cntrl, u32 timeout)
+{
+}
+
+/**
+ * mhi_pm_fast_resume - Resume MHI from a fast/silent suspended state
+ * @mhi_cntrl: MHI controller
+ * @notify_clients: if true, clients will be notified of the resume transition
+ */
+int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_clients)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_pm_fast_suspend - Move MHI into a fast/silent suspended state
+ * @mhi_cntrl: MHI controller
+ * @notify_clients: if true, clients will be notified of the suspend transition
+ */
+int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_clients)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_debug_reg_dump - dump MHI registers for debug purpose
+ * @mhi_cntrl: MHI controller
+ */
+void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl)
+{
+}
+
+/**
+ * mhi_dump_sfr - Print SFR string from RDDM table.
+ * @mhi_cntrl: MHI controller
+ */
+void mhi_dump_sfr(struct mhi_controller *mhi_cntrl)
+{
+}
+
+/**
+ * mhi_device_configure - Allow devices with offload channels to setup their own
+ * channel and event ring context.
+ * @mhi_dev: MHI device
+ * @dir: direction associated with the channel needed to configure
+ * @cfg_tbl: Buffer with ECA/CCA information and data needed to setup context
+ * @elements: Number of items to iterate over from the configuration table
+ */
+int mhi_device_configure(struct mhi_device *mhi_dev,
+ enum dma_data_direction dir,
+ struct mhi_buf *cfg_tbl,
+ int elements)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
+ * registers set by device to indicate rddm readiness for debugging purposes.
+ * @mhi_cntrl: MHI controller
+ * @cookie: cookie/pattern value to match
+ *
+ * Returns:
+ * true if cookie is found
+ * false if cookie is not found
+ */
+bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
+{
+ return false;
+}
+
+/**
+ * mhi_device_get_sync_atomic - Asserts device_wait and moves device to M0
+ * @mhi_dev: Device associated with the channels
+ * @timeout_us: timeout, in micro-seconds
+ * @in_panic: If requested while kernel is in panic state and no ISRs expected
+ *
+ * The device_wake is asserted to keep device in M0 or bring it to M0.
+ * If device is not in M0 state, then this function will wait for device to
+ * move to M0, until @timeout_us elapses.
+ * However, if device's M1 state-change event races with this function
+ * then there is a possiblity of device moving from M0 to M2 and back
+ * to M0. That can't be avoided as host must transition device from M1 to M2
+ * as per the spec.
+ * Clients can ignore that transition after this function returns as the device
+ * is expected to immediately move from M2 to M0 as wake is asserted and
+ * wouldn't enter low power state.
+ * If in_panic boolean is set, no ISRs are expected, hence this API will have to
+ * resort to reading the MHI status register and poll on M0 state change.
+ *
+ * Returns:
+ * 0 if operation was successful (however, M0 -> M2 -> M0 is possible later) as
+ * mentioned above.
+ * -ETIMEDOUT is device faled to move to M0 before @timeout_us elapsed
+ * -EIO if the MHI state is one of the ERROR states.
+ */
+int mhi_device_get_sync_atomic(struct mhi_device *mhi_dev, int timeout_us,
+ bool in_panic)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_controller_set_bw_scale_cb - Set the BW scale callback for MHI controller
+ * @mhi_cntrl: MHI controller
+ * @cb_func: Callback to set for the MHI controller to receive BW scale requests
+ */
+void mhi_controller_set_bw_scale_cb(struct mhi_controller *mhi_cntrl,
+ int (*cb_func)(struct mhi_controller *mhi_cntrl,
+ struct mhi_link_info *link_info))
+{
+}
+
+/**
+ * mhi_controller_set_base - Set the controller base / resource start address
+ * @mhi_cntrl: MHI controller
+ * @base: Physical address to be set for future reference
+ */
+void mhi_controller_set_base(struct mhi_controller *mhi_cntrl,
+ phys_addr_t base)
+{
+}
+
+/**
+ * mhi_get_channel_db_base - retrieve the channel doorbell base address
+ * @mhi_dev: Device associated with the channels
+ * @value: Pointer to an address value which will be populated
+ */
+int mhi_get_channel_db_base(struct mhi_device *mhi_dev, phys_addr_t *value)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_get_event_ring_db_base - retrieve the event ring doorbell base address
+ * @mhi_dev: Device associated with the channels
+ * @value: Pointer to an address value which will be populated
+ */
+int mhi_get_event_ring_db_base(struct mhi_device *mhi_dev, phys_addr_t *value)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_get_device_for_channel - get the MHI device for a specific channel number
+ * @mhi_cntrl: MHI controller
+ * @channel - channel number
+ *
+ * Returns:
+ * Pointer to the MHI device associated with the channel
+ */
+struct mhi_device *mhi_get_device_for_channel(struct mhi_controller *mhi_cntrl,
+ u32 channel)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+/**
+ * mhi_device_ioctl - user space IOCTL support for MHI channels
+ * Native support for setting TIOCM
+ * @mhi_dev: Device associated with the channels
+ * @cmd: IOCTL cmd
+ * @arg: Optional parameter, iotcl cmd specific
+ */
+long mhi_device_ioctl(struct mhi_device *mhi_dev, unsigned int cmd,
+ unsigned long arg)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_controller_set_sfr_support - Set support for subsystem failure reason
+ * @mhi_cntrl: MHI controller
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_controller_set_sfr_support(struct mhi_controller *mhi_cntrl,
+ size_t len)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_controller_setup_timesync - Set support for time synchronization feature
+ * @mhi_cntrl: MHI controller
+ * @time_get: Callback to set for the MHI controller to receive host time
+ * @lpm_disable: Callback to set for the MHI controller to disable link LPM
+ * @lpm_enable: Callback to set for the MHI controller to enable link LPM
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_controller_setup_timesync(struct mhi_controller *mhi_cntrl,
+ u64 (*time_get)(struct mhi_controller *c),
+ int (*lpm_disable)(struct mhi_controller *c),
+ int (*lpm_enable)(struct mhi_controller *c))
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_get_remote_time_sync - Get external soc time relative to local soc time
+ * using MMIO method.
+ * @mhi_dev: Device associated with the channels
+ * @t_host: Pointer to output local soc time
+ * @t_dev: Pointer to output remote soc time
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
+ u64 *t_host,
+ u64 *t_dev)
+{
+ return -EPERM;
+}
+
+/**
+ * mhi_get_remote_time - Get external modem time relative to host time
+ * Trigger event to capture modem time, also capture host time so client
+ * can do a relative drift comparision.
+ * Recommended only tsync device calls this method and do not call this
+ * from atomic context
+ * @mhi_dev: Device associated with the channels
+ * @sequence:unique sequence id track event
+ * @cb_func: callback function to call back
+ *
+ * Returns:
+ * 0 for success, error code for failure
+ */
+int mhi_get_remote_time(struct mhi_device *mhi_dev,
+ u32 sequence,
+ void (*cb_func)(struct mhi_device *mhi_dev,
+ u32 sequence,
+ u64 local_time,
+ u64 remote_time))
+{
+ return -EPERM;
+}
+
+#endif /* CONFIG_MHI_BUS_MISC */
+
+#endif /* _MHI_MISC_H_ */
diff --git a/inc/soc/qcom/qmi.h b/inc/soc/qcom/qmi.h
new file mode 100644
index 0000000..e712f94
--- /dev/null
+++ b/inc/soc/qcom/qmi.h
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017, Linaro Ltd.
+ */
+#ifndef __QMI_HELPERS_H__
+#define __QMI_HELPERS_H__
+
+#include <linux/completion.h>
+#include <linux/idr.h>
+#include <linux/list.h>
+#include <linux/qrtr.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+struct socket;
+
+/**
+ * qmi_header - wireformat header of QMI messages
+ * @type: type of message
+ * @txn_id: transaction id
+ * @msg_id: message id
+ * @msg_len: length of message payload following header
+ */
+struct qmi_header {
+ u8 type;
+ u16 txn_id;
+ u16 msg_id;
+ u16 msg_len;
+} __packed;
+
+#define QMI_REQUEST 0
+#define QMI_RESPONSE 2
+#define QMI_INDICATION 4
+
+#define QMI_COMMON_TLV_TYPE 0
+
+enum qmi_elem_type {
+ QMI_EOTI,
+ QMI_OPT_FLAG,
+ QMI_DATA_LEN,
+ QMI_UNSIGNED_1_BYTE,
+ QMI_UNSIGNED_2_BYTE,
+ QMI_UNSIGNED_4_BYTE,
+ QMI_UNSIGNED_8_BYTE,
+ QMI_SIGNED_2_BYTE_ENUM,
+ QMI_SIGNED_4_BYTE_ENUM,
+ QMI_STRUCT,
+ QMI_STRING,
+};
+
+enum qmi_array_type {
+ NO_ARRAY,
+ STATIC_ARRAY,
+ VAR_LEN_ARRAY,
+};
+
+/**
+ * struct qmi_elem_info - describes how to encode a single QMI element
+ * @data_type: Data type of this element.
+ * @elem_len: Array length of this element, if an array.
+ * @elem_size: Size of a single instance of this data type.
+ * @array_type: Array type of this element.
+ * @tlv_type: QMI message specific type to identify which element
+ * is present in an incoming message.
+ * @offset: Specifies the offset of the first instance of this
+ * element in the data structure.
+ * @ei_array: Null-terminated array of @qmi_elem_info to describe nested
+ * structures.
+ */
+struct qmi_elem_info {
+ enum qmi_elem_type data_type;
+ u32 elem_len;
+ u32 elem_size;
+ enum qmi_array_type array_type;
+ u8 tlv_type;
+ u32 offset;
+ struct qmi_elem_info *ei_array;
+};
+
+#define QMI_RESULT_SUCCESS_V01 0
+#define QMI_RESULT_FAILURE_V01 1
+
+#define QMI_ERR_NONE_V01 0
+#define QMI_ERR_MALFORMED_MSG_V01 1
+#define QMI_ERR_NO_MEMORY_V01 2
+#define QMI_ERR_INTERNAL_V01 3
+#define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 5
+#define QMI_ERR_INVALID_ID_V01 41
+#define QMI_ERR_ENCODING_V01 58
+#define QMI_ERR_DISABLED_V01 69
+#define QMI_ERR_INCOMPATIBLE_STATE_V01 90
+#define QMI_ERR_NOT_SUPPORTED_V01 94
+
+/**
+ * qmi_response_type_v01 - common response header (decoded)
+ * @result: result of the transaction
+ * @error: error value, when @result is QMI_RESULT_FAILURE_V01
+ */
+struct qmi_response_type_v01 {
+ u16 result;
+ u16 error;
+};
+
+extern struct qmi_elem_info qmi_response_type_v01_ei[];
+
+/**
+ * struct qmi_service - context to track lookup-results
+ * @service: service type
+ * @version: version of the @service
+ * @instance: instance id of the @service
+ * @node: node of the service
+ * @port: port of the service
+ * @priv: handle for client's use
+ * @list_node: list_head for house keeping
+ */
+struct qmi_service {
+ unsigned int service;
+ unsigned int version;
+ unsigned int instance;
+
+ unsigned int node;
+ unsigned int port;
+
+ void *priv;
+ struct list_head list_node;
+};
+
+struct qmi_handle;
+
+/**
+ * struct qmi_ops - callbacks for qmi_handle
+ * @new_server: inform client of a new_server lookup-result, returning
+ * successfully from this call causes the library to call
+ * @del_server as the service is removed from the
+ * lookup-result. @priv of the qmi_service can be used by
+ * the client
+ * @del_server: inform client of a del_server lookup-result
+ * @net_reset: inform client that the name service was restarted and
+ * that and any state needs to be released
+ * @msg_handler: invoked for incoming messages, allows a client to
+ * override the usual QMI message handler
+ * @bye: inform a client that all clients from a node are gone
+ * @del_client: inform a client that a particular client is gone
+ */
+struct qmi_ops {
+ int (*new_server)(struct qmi_handle *qmi, struct qmi_service *svc);
+ void (*del_server)(struct qmi_handle *qmi, struct qmi_service *svc);
+ void (*net_reset)(struct qmi_handle *qmi);
+ void (*msg_handler)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
+ const void *data, size_t count);
+ void (*bye)(struct qmi_handle *qmi, unsigned int node);
+ void (*del_client)(struct qmi_handle *qmi,
+ unsigned int node, unsigned int port);
+};
+
+/**
+ * struct qmi_txn - transaction context
+ * @qmi: QMI handle this transaction is associated with
+ * @id: transaction id
+ * @lock: for synchronization between handler and waiter of messages
+ * @completion: completion object as the transaction receives a response
+ * @result: result code for the completed transaction
+ * @ei: description of the QMI encoded response (optional)
+ * @dest: destination buffer to decode message into (optional)
+ */
+struct qmi_txn {
+ struct qmi_handle *qmi;
+
+ u16 id;
+
+ struct mutex lock;
+ struct completion completion;
+ int result;
+
+ struct qmi_elem_info *ei;
+ void *dest;
+};
+
+/**
+ * struct qmi_msg_handler - description of QMI message handler
+ * @type: type of message
+ * @msg_id: message id
+ * @ei: description of the QMI encoded message
+ * @decoded_size: size of the decoded object
+ * @fn: function to invoke as the message is decoded
+ */
+struct qmi_msg_handler {
+ unsigned int type;
+ unsigned int msg_id;
+
+ struct qmi_elem_info *ei;
+
+ size_t decoded_size;
+ void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
+ struct qmi_txn *txn, const void *decoded);
+};
+
+/**
+ * struct qmi_handle - QMI context
+ * @sock: socket handle
+ * @sock_lock: synchronization of @sock modifications
+ * @sq: sockaddr of @sock
+ * @work: work for handling incoming messages
+ * @wq: workqueue to post @work on
+ * @recv_buf: scratch buffer for handling incoming messages
+ * @recv_buf_size: size of @recv_buf
+ * @lookups: list of registered lookup requests
+ * @lookup_results: list of lookup-results advertised to the client
+ * @services: list of registered services (by this client)
+ * @ops: reference to callbacks
+ * @txns: outstanding transactions
+ * @txn_lock: lock for modifications of @txns
+ * @handlers: list of handlers for incoming messages
+ */
+struct qmi_handle {
+ struct socket *sock;
+ struct mutex sock_lock;
+
+ struct sockaddr_qrtr sq;
+
+ struct work_struct work;
+ struct workqueue_struct *wq;
+
+ void *recv_buf;
+ size_t recv_buf_size;
+
+ struct list_head lookups;
+ struct list_head lookup_results;
+ struct list_head services;
+
+ struct qmi_ops ops;
+
+ struct idr txns;
+ struct mutex txn_lock;
+
+ const struct qmi_msg_handler *handlers;
+};
+
+int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service,
+ unsigned int version, unsigned int instance);
+int qmi_add_server(struct qmi_handle *qmi, unsigned int service,
+ unsigned int version, unsigned int instance);
+
+int qmi_handle_init(struct qmi_handle *qmi, size_t max_msg_len,
+ const struct qmi_ops *ops,
+ const struct qmi_msg_handler *handlers);
+void qmi_handle_release(struct qmi_handle *qmi);
+
+ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
+ struct qmi_txn *txn, int msg_id, size_t len,
+ struct qmi_elem_info *ei, const void *c_struct);
+ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
+ struct qmi_txn *txn, int msg_id, size_t len,
+ struct qmi_elem_info *ei, const void *c_struct);
+ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
+ int msg_id, size_t len, struct qmi_elem_info *ei,
+ const void *c_struct);
+
+void *qmi_encode_message(int type, unsigned int msg_id, size_t *len,
+ unsigned int txn_id, struct qmi_elem_info *ei,
+ const void *c_struct);
+
+int qmi_decode_message(const void *buf, size_t len,
+ struct qmi_elem_info *ei, void *c_struct);
+
+int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn,
+ struct qmi_elem_info *ei, void *c_struct);
+int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout);
+void qmi_txn_cancel(struct qmi_txn *txn);
+
+#endif