Add samsung specific changes
This commit is contained in:
419
include/linux/firmware/cirrus/cl_dsp.h
Normal file
419
include/linux/firmware/cirrus/cl_dsp.h
Normal file
@@ -0,0 +1,419 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* cl_dsp.h -- DSP control for non-ALSA Cirrus Logic devices
|
||||
*
|
||||
* Copyright 2021 Cirrus Logic, Inc.
|
||||
*
|
||||
* Author: Fred Treven <fred.treven@cirrus.com>
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#ifndef __CL_DSP_H__
|
||||
#define __CL_DSP_H__
|
||||
|
||||
#define CL_DSP_BYTES_PER_WORD 4
|
||||
#define CL_DSP_BITS_PER_BYTE 8
|
||||
|
||||
#define CL_DSP_BYTE_MASK GENMASK(7, 0)
|
||||
#define CL_DSP_NIBBLE_MASK GENMASK(15, 0)
|
||||
|
||||
#define CL_DSP_FW_FILE_HEADER_SIZE 40
|
||||
#define CL_DSP_COEFF_FILE_HEADER_SIZE 16
|
||||
|
||||
#define CL_DSP_MAGIC_ID_SIZE 4
|
||||
|
||||
#define CL_DSP_WMFW_MAGIC_ID "WMFW"
|
||||
#define CL_DSP_WMDR_MAGIC_ID "WMDR"
|
||||
|
||||
#define CL_DSP_DBLK_HEADER_SIZE 8
|
||||
#define CL_DSP_COEFF_DBLK_HEADER_SIZE 20
|
||||
|
||||
#define CL_DSP_ALIGN 0x00000003
|
||||
|
||||
#define CL_DSP_TARGET_CORE_ADSP1 0x01
|
||||
#define CL_DSP_TARGET_CORE_ADSP2 0x02
|
||||
#define CL_DSP_TARGET_CORE_HALO 0x04
|
||||
#define CL_DSP_TARGET_CORE_WARP2 0x12
|
||||
#define CL_DSP_TARGET_CORE_MCU 0x45
|
||||
|
||||
#define CL_DSP_MIN_FORMAT_VERSION 0x03
|
||||
#define CL_DSP_API_REVISION 0x0300
|
||||
|
||||
#define CL_DSP_ALGO_NAME_LEN_SIZE 1
|
||||
#define CL_DSP_ALGO_DESC_LEN_SIZE 2
|
||||
#define CL_DSP_ALGO_ID_SIZE 4
|
||||
#define CL_DSP_COEFF_COUNT_SIZE 4
|
||||
#define CL_DSP_COEFF_OFFSET_SIZE 2
|
||||
#define CL_DSP_COEFF_TYPE_SIZE 2
|
||||
#define CL_DSP_COEFF_NAME_LEN_SIZE 1
|
||||
#define CL_DSP_COEFF_FULLNAME_LEN_SIZE 1
|
||||
#define CL_DSP_COEFF_DESC_LEN_SIZE 2
|
||||
#define CL_DSP_COEFF_LEN_SIZE 4
|
||||
#define CL_DSP_COEFF_FLAGS_SIZE 4
|
||||
#define CL_DSP_COEFF_FLAGS_SHIFT 16
|
||||
#define CL_DSP_COEFF_NAME_LEN_MAX 32
|
||||
#define CL_DSP_COEFF_MIN_FORMAT_VERSION 0x01
|
||||
#define CL_DSP_COEFF_API_REV_HALO 0x030000
|
||||
#define CL_DSP_COEFF_API_REV_ADSP2 0x000500
|
||||
|
||||
#define CL_DSP_ALGO_LIST_TERM 0xBEDEAD
|
||||
|
||||
#define CL_DSP_REV_OFFSET_SHIFT 8
|
||||
|
||||
#define CL_DSP_REV_MAJOR_MASK GENMASK(23, 16)
|
||||
#define CL_DSP_REV_MAJOR_SHIFT 16
|
||||
#define CL_DSP_REV_MINOR_MASK GENMASK(15, 8)
|
||||
#define CL_DSP_REV_MINOR_SHIFT 8
|
||||
#define CL_DSP_REV_PATCH_MASK GENMASK(7, 0)
|
||||
|
||||
#define CL_DSP_NUM_ALGOS_MAX 32
|
||||
|
||||
#ifndef CONFIG_CS40L26_SAMSUNG_USE_MAX_DATA_TX_SIZE
|
||||
#define CL_DSP_MAX_WLEN 32
|
||||
#else
|
||||
#define CL_DSP_MAX_WLEN 4096
|
||||
#endif
|
||||
#define CL_DSP_XM_UNPACKED_TYPE 0x0005
|
||||
#define CL_DSP_YM_UNPACKED_TYPE 0x0006
|
||||
#define CL_DSP_PM_PACKED_TYPE 0x0010
|
||||
#define CL_DSP_XM_PACKED_TYPE 0x0011
|
||||
#define CL_DSP_YM_PACKED_TYPE 0x0012
|
||||
#define CL_DSP_ALGO_INFO_TYPE 0x00F2
|
||||
#define CL_DSP_WMFW_INFO_TYPE 0x00FF
|
||||
|
||||
#define CL_DSP_MEM_REG_TYPE_MASK GENMASK(27, 20)
|
||||
#define CL_DSP_MEM_REG_TYPE_SHIFT 20
|
||||
|
||||
#define CL_DSP_PM_NUM_BYTES 5
|
||||
#define CL_DSP_PACKED_NUM_BYTES 3
|
||||
#define CL_DSP_UNPACKED_NUM_BYTES 4
|
||||
|
||||
#define CL_DSP_WMDR_DBLK_OFFSET_SIZE 2
|
||||
#define CL_DSP_WMDR_DBLK_TYPE_SIZE 2
|
||||
#define CL_DSP_WMDR_ALGO_ID_SIZE 4
|
||||
#define CL_DSP_WMDR_ALGO_REV_SIZE 4
|
||||
#define CL_DSP_WMDR_SAMPLE_RATE_SIZE 4
|
||||
#define CL_DSP_WMDR_DBLK_LEN_SIZE 4
|
||||
#define CL_DSP_WMDR_NAME_LEN 32
|
||||
#define CL_DSP_WMDR_DATE_LEN 16
|
||||
#define CL_DSP_WMDR_HEADER_LEN_SIZE 4
|
||||
|
||||
#define CL_DSP_WMDR_DATE_PREFIX "Date: "
|
||||
#define CL_DSP_WMDR_DATE_PREFIX_LEN 6
|
||||
|
||||
#define CL_DSP_WMDR_FILE_NAME_MISSING "N/A"
|
||||
#define CL_DSP_WMDR_FILE_DATE_MISSING "N/A"
|
||||
|
||||
#define CL_DSP_WMDR_NAME_TYPE 0xFE00
|
||||
#define CL_DSP_WMDR_INFO_TYPE 0xFF00
|
||||
|
||||
/* HALO core */
|
||||
#define CL_DSP_HALO_XMEM_PACKED_BASE 0x02000000
|
||||
#define CL_DSP_HALO_XROM_PACKED_BASE 0x02006000
|
||||
#define CL_DSP_HALO_XMEM_UNPACKED32_BASE 0x02400000
|
||||
#define CL_DSP_HALO_XMEM_UNPACKED24_BASE 0x02800000
|
||||
#define CL_DSP_HALO_XROM_UNPACKED24_BASE 0x02808000
|
||||
#define CL_DSP_HALO_YMEM_PACKED_BASE 0x02C00000
|
||||
#define CL_DSP_HALO_YMEM_UNPACKED32_BASE 0x03000000
|
||||
#define CL_DSP_HALO_YMEM_UNPACKED24_BASE 0x03400000
|
||||
#define CL_DSP_HALO_PMEM_BASE 0x03800000
|
||||
#define CL_DSP_HALO_PROM_BASE 0x03C60000
|
||||
|
||||
#define CL_DSP_HALO_XM_FW_ID_REG 0x0280000C
|
||||
#define CL_DSP_HALO_NUM_ALGOS_REG 0x02800024
|
||||
|
||||
#define CL_DSP_HALO_ALGO_REV_OFFSET 4
|
||||
#define CL_DSP_HALO_ALGO_XM_BASE_OFFSET 8
|
||||
#define CL_DSP_HALO_ALGO_XM_SIZE_OFFSET 12
|
||||
#define CL_DSP_HALO_ALGO_YM_BASE_OFFSET 16
|
||||
#define CL_DSP_HALO_ALGO_YM_SIZE_OFFSET 20
|
||||
#define CL_DSP_ALGO_ENTRY_SIZE 24
|
||||
|
||||
#define CL_DSP_HALO_FLAG_READ BIT(0)
|
||||
#define CL_DSP_HALO_FLAG_WRITE BIT(1)
|
||||
#define CL_DSP_HALO_FLAG_VOLATILE BIT(2)
|
||||
|
||||
/* open wavetable */
|
||||
#define CL_DSP_OWT_HEADER_MAX_LEN 254
|
||||
#define CL_DSP_OWT_HEADER_ENTRY_SIZE 12
|
||||
|
||||
/* Waveform metadata */
|
||||
#define CL_DSP_SVC_ID 1
|
||||
#define CL_DSP_SVC_LEN 1
|
||||
#define CL_DSP_MD_SIZE_MAX_BYTES 28
|
||||
#define CL_DSP_MD_PRESENT BIT(10)
|
||||
#define CL_DSP_MD_TERMINATOR 0xFFFFFF
|
||||
#define CL_DSP_MD_TYPE_MASK GENMASK(23, 16)
|
||||
#define CL_DSP_MD_LENGTH_MASK GENMASK(15, 8)
|
||||
|
||||
/* macros */
|
||||
#define CL_DSP_WORD_ALIGN(n) (CL_DSP_BYTES_PER_WORD +\
|
||||
(((n) / CL_DSP_BYTES_PER_WORD) *\
|
||||
CL_DSP_BYTES_PER_WORD))
|
||||
|
||||
#define CL_DSP_GET_MAJOR(n) (((n) & CL_DSP_REV_MAJOR_MASK) >>\
|
||||
CL_DSP_REV_MAJOR_SHIFT)
|
||||
|
||||
#define CL_DSP_GET_MINOR(n) (((n) & CL_DSP_REV_MINOR_MASK) >>\
|
||||
CL_DSP_REV_MINOR_SHIFT)
|
||||
|
||||
#define CL_DSP_GET_PATCH(n) ((n) & CL_DSP_REV_PATCH_MASK)
|
||||
|
||||
#define CL_DSP_MEM_REGION_PREFIX(n) (((n) & CL_DSP_MEM_REG_TYPE_MASK) >>\
|
||||
CL_DSP_MEM_REG_TYPE_SHIFT)
|
||||
|
||||
enum cl_dsp_wt_type {
|
||||
WT_TYPE_V4_PCM = 0,
|
||||
WT_TYPE_V4_PWLE = 1,
|
||||
WT_TYPE_V4_PCM_F0_REDC = 2,
|
||||
WT_TYPE_V4_PCM_F0_REDC_VAR = 3,
|
||||
WT_TYPE_V4_COMPOSITE = 4,
|
||||
WT_TYPE_V5_PCM_PCM_F0_REDC_Q = 5,
|
||||
WT_TYPE_V5_PWLE_LONG = 6,
|
||||
WT_TYPE_V5_PWLE_LINEAR = 7,
|
||||
WT_TYPE_V6_PCM_F0_REDC = 8,
|
||||
WT_TYPE_V6_PCM_F0_REDC_VAR = 9,
|
||||
WT_TYPE_V6_COMPOSITE = 10,
|
||||
WT_TYPE_V6_PCM_F0_REDC_Q = 11,
|
||||
WT_TYPE_V6_PWLE = 12,
|
||||
|
||||
WT_TYPE_TERMINATOR = 0xFF,
|
||||
};
|
||||
|
||||
union cl_dsp_wmdr_header {
|
||||
struct {
|
||||
char magic[CL_DSP_BYTES_PER_WORD];
|
||||
u32 header_len;
|
||||
u32 fw_revision : 24;
|
||||
u8 file_format_version;
|
||||
u32 api_revision : 24;
|
||||
u8 target_core;
|
||||
} __attribute__((__packed__));
|
||||
u8 data[CL_DSP_COEFF_FILE_HEADER_SIZE];
|
||||
};
|
||||
|
||||
union cl_dsp_wmfw_header {
|
||||
struct {
|
||||
char magic[CL_DSP_BYTES_PER_WORD];
|
||||
u32 header_len;
|
||||
u16 api_revision;
|
||||
u8 target_core;
|
||||
u8 file_format_version;
|
||||
u32 xm_size;
|
||||
u32 ym_size;
|
||||
u32 pm_size;
|
||||
u32 zm_size;
|
||||
u32 timestamp[2];
|
||||
u32 checksum;
|
||||
} __attribute__((__packed__));
|
||||
u8 data[CL_DSP_FW_FILE_HEADER_SIZE];
|
||||
};
|
||||
|
||||
union cl_dsp_data_block_header {
|
||||
struct {
|
||||
u32 start_offset : 24;
|
||||
u8 block_type;
|
||||
u32 data_len;
|
||||
} __attribute__((__packed__));
|
||||
u8 data[CL_DSP_DBLK_HEADER_SIZE];
|
||||
};
|
||||
|
||||
union cl_dsp_coeff_data_block_header {
|
||||
struct {
|
||||
u16 start_offset;
|
||||
u16 block_type;
|
||||
u32 algo_id;
|
||||
u32 algo_rev;
|
||||
u32 sample_rate;
|
||||
u32 data_len;
|
||||
} __attribute__((__packed__));
|
||||
u8 data[CL_DSP_COEFF_DBLK_HEADER_SIZE];
|
||||
};
|
||||
|
||||
struct cl_dsp_data_block {
|
||||
union cl_dsp_data_block_header header;
|
||||
u8 *payload;
|
||||
};
|
||||
|
||||
struct cl_dsp_coeff_data_block {
|
||||
union cl_dsp_coeff_data_block_header header;
|
||||
u8 *payload;
|
||||
};
|
||||
|
||||
struct cl_dsp_coeff_desc {
|
||||
u32 parent_id;
|
||||
char *parent_name;
|
||||
u16 block_offset;
|
||||
u16 block_type;
|
||||
unsigned char name[CL_DSP_COEFF_NAME_LEN_MAX];
|
||||
unsigned int reg;
|
||||
unsigned int flags;
|
||||
unsigned int length;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct cl_dsp_memchunk {
|
||||
u8 *data;
|
||||
u8 *max;
|
||||
int bytes;
|
||||
u32 cache;
|
||||
int cachebits;
|
||||
};
|
||||
|
||||
struct cl_dsp_owt_header {
|
||||
enum cl_dsp_wt_type type;
|
||||
u16 flags;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
void *data;
|
||||
u32 braking_time;
|
||||
};
|
||||
|
||||
struct cl_dsp_owt_desc {
|
||||
struct cl_dsp_owt_header waves[CL_DSP_OWT_HEADER_MAX_LEN];
|
||||
int nwaves;
|
||||
int bytes;
|
||||
u8 *raw_data;
|
||||
};
|
||||
|
||||
struct cl_dsp_wt_desc {
|
||||
unsigned int id;
|
||||
char wt_name_xm[CL_DSP_WMDR_NAME_LEN];
|
||||
char wt_name_ym[CL_DSP_WMDR_NAME_LEN];
|
||||
unsigned int wt_limit_xm;
|
||||
unsigned int wt_limit_ym;
|
||||
char wt_file[CL_DSP_WMDR_NAME_LEN];
|
||||
char wt_date[CL_DSP_WMDR_DATE_LEN];
|
||||
struct cl_dsp_owt_desc owt;
|
||||
bool is_xm;
|
||||
};
|
||||
|
||||
struct cl_dsp_algo_info {
|
||||
unsigned int id;
|
||||
unsigned int rev;
|
||||
unsigned int xm_base;
|
||||
unsigned int xm_size;
|
||||
unsigned int ym_base;
|
||||
unsigned int ym_size;
|
||||
};
|
||||
|
||||
struct cl_dsp {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct list_head coeff_desc_head;
|
||||
unsigned int num_algos;
|
||||
struct cl_dsp_algo_info algo_info[CL_DSP_NUM_ALGOS_MAX + 1];
|
||||
const struct cl_dsp_fw_desc *fw_desc;
|
||||
const struct cl_dsp_mem_reg_desc *mem_reg_desc;
|
||||
const struct cl_dsp_algo_params *algo_params;
|
||||
struct cl_dsp_wt_desc *wt_desc;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
/* Debug Logger */
|
||||
struct cl_dsp_host_buffer {
|
||||
__be32 buf1_base;
|
||||
__be32 buf1_size;
|
||||
__be32 buf2_base;
|
||||
__be32 buf1_buf2_size;
|
||||
__be32 buf3_base;
|
||||
__be32 buf_total_size;
|
||||
__be32 high_water_mark;
|
||||
__be32 irq_count;
|
||||
__be32 irq_ack;
|
||||
__be32 next_write_index;
|
||||
__be32 next_read_index;
|
||||
__be32 error;
|
||||
__be32 oldest_block_index;
|
||||
__be32 requested_rewind;
|
||||
__be32 reserved_space;
|
||||
__be32 min_free;
|
||||
__be32 blocks_written[2];
|
||||
__be32 words_written[2];
|
||||
} __packed;
|
||||
|
||||
struct cl_dsp_logger {
|
||||
u32 *buf_data;
|
||||
u32 buf_data_size;
|
||||
u32 algo_id;
|
||||
u32 host_buf_ptr;
|
||||
u32 host_buf_base;
|
||||
int host_buf_size_words;
|
||||
u32 high_watermark;
|
||||
};
|
||||
|
||||
struct cl_dsp_debugfs {
|
||||
struct cl_dsp *core;
|
||||
struct dentry *debugfs_root;
|
||||
struct dentry *debugfs_node;
|
||||
struct mutex lock;
|
||||
struct cl_dsp_logger dl;
|
||||
};
|
||||
|
||||
#define CL_DSP_DEBUGFS_NUM_CONTROLS 3
|
||||
#define CL_DSP_DEBUGFS_RW_FILE_MODE 0600
|
||||
#define CL_DSP_DEBUGFS_RO_FILE_MODE 0400
|
||||
#define CL_DSP_DEBUGFS_WO_FILE_MOADE 0200
|
||||
#define CL_DSP_DEBUGFS_TRACE_LOG_STRING_SIZE 3
|
||||
#define CL_DSP_DEBUGFS_TRACE_LOG_DISABLE 0
|
||||
#define CL_DSP_DEBUGFS_TRACE_LOG_ENABLE 1
|
||||
|
||||
#define CL_DSP_HOST_BUFFER_DATA_MASK 0x00FFFFFFu
|
||||
#define CL_DSP_HOST_BUFFER_ERROR_OVERFLOW BIT(0)
|
||||
#define CL_DSP_HOST_BUFFER_READ_INDEX_RESET 0x00FFFFFF
|
||||
#define CL_DSP_HOST_BUFFER_IRQ_MASK BIT(0)
|
||||
#define CL_DSP_HOST_BUFFER_DATA_SLOT_SIZE 10
|
||||
|
||||
#define HOST_BUFFER_FIELD(field) (offsetof(struct cl_dsp_host_buffer, field) / sizeof(__be32))
|
||||
|
||||
|
||||
int cl_dsp_logger_update(struct cl_dsp_debugfs *db);
|
||||
struct cl_dsp_debugfs *cl_dsp_debugfs_create(struct cl_dsp *dsp,
|
||||
struct dentry *parent_node, u32 event_log_algo_id);
|
||||
void cl_dsp_debugfs_destroy(struct cl_dsp_debugfs *db);
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
/* Exported Functions */
|
||||
struct cl_dsp *cl_dsp_create(struct device *dev, struct regmap *regmap);
|
||||
int cl_dsp_destroy(struct cl_dsp *dsp);
|
||||
int cl_dsp_wavetable_create(struct cl_dsp *dsp, unsigned int id,
|
||||
const char *wt_name_xm, const char *wt_name_ym,
|
||||
const char *wt_file);
|
||||
int cl_dsp_firmware_parse(struct cl_dsp *dsp, const struct firmware *fw,
|
||||
bool write_fw);
|
||||
int cl_dsp_coeff_file_parse(struct cl_dsp *dsp, const struct firmware *fw);
|
||||
int cl_dsp_get_reg(struct cl_dsp *dsp, const char *coeff_name,
|
||||
const unsigned int block_type, const unsigned int algo_id,
|
||||
unsigned int *reg);
|
||||
int cl_dsp_get_flags(struct cl_dsp *dsp, const char *coeff_name,
|
||||
const unsigned int block_type, const unsigned int algo_id,
|
||||
unsigned int *flags);
|
||||
int cl_dsp_get_length(struct cl_dsp *dsp, const char *coeff_name,
|
||||
const unsigned int block_type, const unsigned int algo_id,
|
||||
size_t *length);
|
||||
bool cl_dsp_algo_is_present(struct cl_dsp *dsp, const unsigned int algo_id);
|
||||
struct cl_dsp_memchunk cl_dsp_memchunk_create(void *data, int size);
|
||||
int cl_dsp_memchunk_write(struct cl_dsp_memchunk *ch, int nbits, u32 val);
|
||||
inline bool cl_dsp_memchunk_end(struct cl_dsp_memchunk *ch);
|
||||
int cl_dsp_memchunk_read(struct cl_dsp *dsp, struct cl_dsp_memchunk *ch,
|
||||
int nbits, void *val);
|
||||
int cl_dsp_memchunk_flush(struct cl_dsp_memchunk *ch);
|
||||
int cl_dsp_raw_write(struct cl_dsp *dsp, unsigned int reg,
|
||||
const void *val, size_t val_len, size_t limit);
|
||||
int cl_dsp_fw_id_get(struct cl_dsp *dsp, unsigned int *id);
|
||||
int cl_dsp_fw_rev_get(struct cl_dsp *dsp, unsigned int *rev);
|
||||
|
||||
#endif /* __CL_DSP_H */
|
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2015 Linaro Ltd.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef __QCOM_SCM_H
|
||||
#define __QCOM_SCM_H
|
||||
@@ -15,6 +16,19 @@
|
||||
#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0
|
||||
#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1
|
||||
#define QCOM_SCM_HDCP_MAX_REQ_CNT 5
|
||||
#define QCOM_SCM_CAMERA_MAX_QOS_CNT 20
|
||||
|
||||
struct qcom_scm_camera_qos {
|
||||
u32 offset;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
enum qcom_download_mode {
|
||||
QCOM_DOWNLOAD_NODUMP = 0x00,
|
||||
QCOM_DOWNLOAD_EDL = 0x01,
|
||||
QCOM_DOWNLOAD_FULLDUMP = 0x10,
|
||||
QCOM_DOWNLOAD_MINIDUMP = 0x20,
|
||||
};
|
||||
|
||||
struct qcom_scm_hdcp_req {
|
||||
u32 addr;
|
||||
@@ -46,6 +60,19 @@ enum qcom_scm_sec_dev_id {
|
||||
QCOM_SCM_ICE_DEV_ID = 20,
|
||||
};
|
||||
|
||||
struct qcom_scm_current_perm_info {
|
||||
__le32 vmid;
|
||||
__le32 perm;
|
||||
__le64 ctx;
|
||||
__le32 ctx_size;
|
||||
__le32 unused;
|
||||
};
|
||||
|
||||
struct qcom_scm_mem_map_info {
|
||||
__le64 mem_addr;
|
||||
__le64 mem_size;
|
||||
};
|
||||
|
||||
enum qcom_scm_ice_cipher {
|
||||
QCOM_SCM_ICE_CIPHER_AES_128_XTS = 0,
|
||||
QCOM_SCM_ICE_CIPHER_AES_128_CBC = 1,
|
||||
@@ -56,16 +83,75 @@ enum qcom_scm_ice_cipher {
|
||||
#define QCOM_SCM_PERM_READ 0x4
|
||||
#define QCOM_SCM_PERM_WRITE 0x2
|
||||
#define QCOM_SCM_PERM_EXEC 0x1
|
||||
|
||||
#define QCOM_SCM_VMID_TZ 0x1
|
||||
#define QCOM_SCM_VMID_HLOS 0x3
|
||||
#define QCOM_SCM_VMID_CP_TOUCH 0x8
|
||||
#define QCOM_SCM_VMID_CP_BITSTREAM 0x9
|
||||
#define QCOM_SCM_VMID_CP_PIXEL 0xA
|
||||
#define QCOM_SCM_VMID_CP_NON_PIXEL 0xB
|
||||
#define QCOM_SCM_VMID_CP_CAMERA 0xD
|
||||
#define QCOM_SCM_VMID_HLOS_FREE 0xE
|
||||
#define QCOM_SCM_VMID_MSS_MSA 0xF
|
||||
#define QCOM_SCM_VMID_MSS_NONMSA 0x10
|
||||
#define QCOM_SCM_VMID_CP_SEC_DISPLAY 0x11
|
||||
#define QCOM_SCM_VMID_CP_APP 0x12
|
||||
#define QCOM_SCM_VMID_LPASS 0x16
|
||||
#define QCOM_SCM_VMID_WLAN 0x18
|
||||
#define QCOM_SCM_VMID_WLAN_CE 0x19
|
||||
#define QCOM_SCM_VMID_CP_SPSS_SP 0x1A
|
||||
#define QCOM_SCM_VMID_CP_CAMERA_PREVIEW 0x1D
|
||||
#define QCOM_SCM_VMID_CDSP 0x1E
|
||||
#define QCOM_SCM_VMID_CP_SPSS_SP_SHARED 0x22
|
||||
#define QCOM_SCM_VMID_CP_SPSS_HLOS_SHARED 0x24
|
||||
#define QCOM_SCM_VMID_ADSP_HEAP 0x25
|
||||
#define QCOM_SCM_VMID_CP_CDSP 0x2A
|
||||
#define QCOM_SCM_VMID_NAV 0x2B
|
||||
#define QCOM_SCM_VMID_TVM 0x2D
|
||||
#define QCOM_SCM_VMID_OEMVM 0x31
|
||||
#define QCOM_SCM_VMID_SOCCP 0x3C
|
||||
|
||||
#define QCOM_SCM_PERM_RW (QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE)
|
||||
#define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC)
|
||||
|
||||
static inline void qcom_scm_populate_vmperm_info(
|
||||
struct qcom_scm_current_perm_info *destvm, int vmid, int perm)
|
||||
{
|
||||
if (!destvm)
|
||||
return;
|
||||
|
||||
destvm->vmid = cpu_to_le32(vmid);
|
||||
destvm->perm = cpu_to_le32(perm);
|
||||
destvm->ctx = 0;
|
||||
destvm->ctx_size = 0;
|
||||
}
|
||||
|
||||
static inline void qcom_scm_populate_mem_map_info(
|
||||
struct qcom_scm_mem_map_info *mem_to_map,
|
||||
phys_addr_t mem_addr, size_t mem_size)
|
||||
{
|
||||
if (!mem_to_map)
|
||||
return;
|
||||
|
||||
mem_to_map->mem_addr = cpu_to_le64(mem_addr);
|
||||
mem_to_map->mem_size = cpu_to_le64(mem_size);
|
||||
}
|
||||
|
||||
extern bool qcom_scm_is_available(void);
|
||||
|
||||
extern int qcom_scm_set_cold_boot_addr(void *entry);
|
||||
extern int qcom_scm_set_warm_boot_addr(void *entry);
|
||||
extern void qcom_scm_cpu_power_down(u32 flags);
|
||||
extern int qcom_scm_sec_wdog_deactivate(void);
|
||||
extern int qcom_scm_sec_wdog_trigger(void);
|
||||
extern void qcom_scm_disable_sdi(void);
|
||||
extern int qcom_scm_set_remote_state(u32 state, u32 id);
|
||||
|
||||
extern int qcom_scm_spin_cpu(void);
|
||||
extern void qcom_scm_set_download_mode(enum qcom_download_mode mode);
|
||||
extern int qcom_scm_get_download_mode(unsigned int *mode);
|
||||
extern int qcom_scm_config_cpu_errata(void);
|
||||
|
||||
struct qcom_scm_pas_metadata {
|
||||
void *ptr;
|
||||
dma_addr_t phys;
|
||||
@@ -74,16 +160,27 @@ struct qcom_scm_pas_metadata {
|
||||
|
||||
extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
|
||||
size_t size,
|
||||
struct qcom_scm_pas_metadata *ctx);
|
||||
extern void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
|
||||
struct qcom_scm_pas_metadata *ctx,
|
||||
struct device *dev);
|
||||
|
||||
extern void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx,
|
||||
struct device *dev);
|
||||
extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
|
||||
phys_addr_t size);
|
||||
extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
|
||||
extern int qcom_scm_pas_shutdown(u32 peripheral);
|
||||
extern int qcom_scm_pas_shutdown_retry(u32 peripheral);
|
||||
extern bool qcom_scm_pas_supported(u32 peripheral);
|
||||
|
||||
extern int qcom_scm_get_sec_dump_state(u32 *dump_state);
|
||||
extern int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size);
|
||||
|
||||
extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
|
||||
extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
|
||||
extern int qcom_scm_io_reset(void);
|
||||
|
||||
extern bool qcom_scm_is_secure_wdog_trigger_available(void);
|
||||
extern bool qcom_scm_is_mode_switch_available(void);
|
||||
|
||||
extern bool qcom_scm_restore_sec_cfg_available(void);
|
||||
extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
|
||||
@@ -93,10 +190,39 @@ extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);
|
||||
extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
|
||||
u32 cp_nonpixel_start,
|
||||
u32 cp_nonpixel_size);
|
||||
extern int qcom_scm_mem_protect_region_id(phys_addr_t paddr, size_t size);
|
||||
extern int
|
||||
qcom_scm_assign_mem_regions(struct qcom_scm_mem_map_info *mem_regions,
|
||||
size_t mem_regions_sz, u32 *srcvms, size_t src_sz,
|
||||
struct qcom_scm_current_perm_info *newvms,
|
||||
size_t newvms_sz);
|
||||
extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
|
||||
u64 *src,
|
||||
const struct qcom_scm_vmperm *newvm,
|
||||
unsigned int dest_cnt);
|
||||
extern int qcom_scm_mem_protect_sd_ctrl(u32 devid, phys_addr_t mem_addr,
|
||||
u64 mem_size, u32 vmid);
|
||||
extern int qcom_scm_kgsl_set_smmu_aperture(
|
||||
unsigned int num_context_bank);
|
||||
extern int qcom_scm_kgsl_set_smmu_lpac_aperture(
|
||||
unsigned int num_context_bank);
|
||||
extern int qcom_scm_kgsl_init_regs(u32 gpu_req);
|
||||
extern int qcom_scm_kgsl_dcvs_tuning(u32 mingap, u32 penalty, u32 numbusy);
|
||||
extern int qcom_scm_enable_shm_bridge(void);
|
||||
extern int qcom_scm_delete_shm_bridge(u64 handle);
|
||||
extern int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
|
||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||
u64 ns_vmids, u64 *handle);
|
||||
|
||||
extern bool qcom_scm_dcvs_core_available(void);
|
||||
extern bool qcom_scm_dcvs_ca_available(void);
|
||||
extern int qcom_scm_dcvs_reset(void);
|
||||
extern int qcom_scm_dcvs_init_v2(phys_addr_t addr, size_t size, int *version);
|
||||
extern int qcom_scm_dcvs_init_ca_v2(phys_addr_t addr, size_t size);
|
||||
extern int qcom_scm_dcvs_update(int level, s64 total_time, s64 busy_time);
|
||||
extern int qcom_scm_dcvs_update_v2(int level, s64 total_time, s64 busy_time);
|
||||
extern int qcom_scm_dcvs_update_ca_v2(int level, s64 total_time, s64 busy_time,
|
||||
int context_count);
|
||||
|
||||
extern bool qcom_scm_ocmem_lock_available(void);
|
||||
extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
|
||||
@@ -104,6 +230,13 @@ extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
|
||||
extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset,
|
||||
u32 size);
|
||||
|
||||
extern int qcom_scm_config_set_ice_key(uint32_t index, phys_addr_t paddr,
|
||||
size_t size, uint32_t cipher,
|
||||
unsigned int data_unit,
|
||||
unsigned int ce);
|
||||
extern int qcom_scm_clear_ice_key(uint32_t index, unsigned int ce);
|
||||
extern int qcom_scm_derive_sw_secret(phys_addr_t paddr_key, size_t size_key,
|
||||
phys_addr_t paddr_secret, size_t size_secret);
|
||||
extern bool qcom_scm_ice_available(void);
|
||||
extern int qcom_scm_ice_invalidate_key(u32 index);
|
||||
extern int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
|
||||
@@ -114,12 +247,41 @@ extern bool qcom_scm_hdcp_available(void);
|
||||
extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
|
||||
u32 *resp);
|
||||
|
||||
extern int qcom_scm_lmh_fetch_data(u32 node_id, u32 debug_type, uint32_t *peak,
|
||||
uint32_t *avg);
|
||||
|
||||
extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt);
|
||||
extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
|
||||
extern int qcom_scm_smmu_notify_secure_lut(u64 dev_id, bool secure);
|
||||
|
||||
extern int qcom_scm_camera_update_camnoc_qos(uint32_t use_case_id,
|
||||
uint32_t qos_cnt, struct qcom_scm_camera_qos *scm_buf);
|
||||
extern int qcom_scm_camera_protect_all(uint32_t protect, uint32_t param);
|
||||
extern int qcom_scm_camera_protect_phy_lanes(bool protect, u64 regmask);
|
||||
|
||||
extern int qcom_scm_get_tz_log_feat_id(u64 *version);
|
||||
extern int qcom_scm_get_tz_feat_id_version(u64 feat_id, u64 *version);
|
||||
extern int qcom_scm_register_qsee_log_buf(phys_addr_t buf, size_t len);
|
||||
extern int qcom_scm_query_encrypted_log_feature(u64 *enabled);
|
||||
extern int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len,
|
||||
uint32_t log_id, bool is_full_encrypted_tz_logs_supported,
|
||||
bool is_full_encrypted_tz_logs_enabled);
|
||||
|
||||
extern int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size,
|
||||
phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
|
||||
u64 *response_type, unsigned int *data);
|
||||
extern int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size,
|
||||
phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
|
||||
u64 *response_type, unsigned int *data);
|
||||
extern int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
|
||||
size_t out_buf_size, int32_t *result, u64 *response_type,
|
||||
unsigned int *data);
|
||||
|
||||
extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
|
||||
u64 limit_node, u32 node_id, u64 version);
|
||||
extern int qcom_scm_lmh_profile_change(u32 profile_id);
|
||||
extern bool qcom_scm_lmh_dcvsh_available(void);
|
||||
|
||||
extern int qcom_scm_tsens_reinit(int *tsens_ret);
|
||||
|
||||
#endif
|
||||
|
21
include/linux/firmware/qcom/si_core_xts.h
Normal file
21
include/linux/firmware/qcom/si_core_xts.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SI_CORE_XTS_H__
|
||||
#define _LINUX_SI_CORE_XTS_H__
|
||||
|
||||
#include <linux/firmware/qcom/si_object.h>
|
||||
|
||||
struct si_object *init_si_mem_object_user(struct dma_buf *dma_buf,
|
||||
void (*release)(void *), void *private);
|
||||
|
||||
/* For 'mem_object_to_dma_buf' and 'is_mem_object' caller should own the 'object',
|
||||
* (i.e. someone should have already called '__get_si_object').
|
||||
*/
|
||||
|
||||
int is_mem_object(struct si_object *object);
|
||||
struct dma_buf *mem_object_to_dma_buf(struct si_object *object);
|
||||
|
||||
#endif /* _LINUX_SI_CORE_XTS_H__ */
|
231
include/linux/firmware/qcom/si_object.h
Normal file
231
include/linux/firmware/qcom/si_object.h
Normal file
@@ -0,0 +1,231 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SI_OBJECT_H__
|
||||
#define _LINUX_SI_OBJECT_H__
|
||||
|
||||
#include <linux/kref.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
/* Primordial Object */
|
||||
|
||||
/* It is used for bootstrapping the Mink IPC connection between a VM and QTEE.
|
||||
*
|
||||
* Each side (both the VM and the QTEE) starts up with no object received from the
|
||||
* other side. They both ''assume'' the other side implements a permanent initial
|
||||
* object in the object table.
|
||||
*
|
||||
* QTEE's initial object is typically called the ''root client env'', and it's
|
||||
* invoked by VMs when they want to get a new clientEnv. The initial object created
|
||||
* by the VMs is invoked by QTEE, it's typically called the ''primordial object''.
|
||||
*
|
||||
* To gracefully SWITCH the primordial object, use 'init_si_object_user' with
|
||||
* 'SI_OT_ROOT' type and 'put_si_object' on the previous primordial object. si-core
|
||||
* will issue the release on the old primordial object if QTEE is not using it.
|
||||
*/
|
||||
|
||||
enum si_object_type {
|
||||
SI_OT_USER = 0x1, /* QTEE object. */
|
||||
SI_OT_CB_OBJECT = 0x2, /* Callback Object. */
|
||||
SI_OT_ROOT = 0x8, /* ''Root client env.'' or 'primordial' Object. */
|
||||
SI_OT_NULL = 0x10, /* NULL object. */
|
||||
};
|
||||
|
||||
/* Maximum number of argument that can fit in a QTEE message. */
|
||||
#define MAX_ARGS 64
|
||||
|
||||
struct si_object;
|
||||
|
||||
/**
|
||||
* struct si_arg - argument for QTEE object invocation.
|
||||
* @type: type of argument
|
||||
* @flags: extra flags.
|
||||
* @b: address and size if type of argument is buffer
|
||||
* @o: si_object instance if type of argument is object
|
||||
*/
|
||||
struct si_arg {
|
||||
enum arg_type {
|
||||
SI_AT_END = 0,
|
||||
SI_AT_IB, /* Input Buffer. */
|
||||
SI_AT_OB, /* Output Buffer. */
|
||||
SI_AT_IO, /* Input Object. */
|
||||
SI_AT_OO /* Output Object. */
|
||||
} type;
|
||||
|
||||
/* 'uaddr' holds a __user address. */
|
||||
#define SI_ARG_FLAGS_UADDR 1
|
||||
char flags;
|
||||
union {
|
||||
struct si_buffer {
|
||||
union {
|
||||
void *addr;
|
||||
void __user *uaddr;
|
||||
};
|
||||
size_t size;
|
||||
} b;
|
||||
struct si_object *o;
|
||||
};
|
||||
};
|
||||
|
||||
static inline int size_of_arg(struct si_arg u[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (u[i].type != SI_AT_END)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Context ID - It is a unique ID assigned to a invocation which is in progress.
|
||||
* Objects's dispatcher can use the ID to differentiate between concurrent calls.
|
||||
* ID [0 .. 10) are reserved, i.e. never passed to object's dispatcher.
|
||||
*/
|
||||
|
||||
struct si_object_invoke_ctx {
|
||||
unsigned int context_id;
|
||||
|
||||
#define OIC_FLAG_BUSY 1 /* Context is busy. */
|
||||
#define OIC_FLAG_NOTIFY 2 /* Context needs to notify the current object. */
|
||||
#define OIC_FLAG_QTEE 4 /* Context has objects shared with QTEE. */
|
||||
unsigned int flags;
|
||||
|
||||
/* Current object invoked in this callback context. */
|
||||
struct si_object *object;
|
||||
|
||||
/* Arguments passed to dispatch callback. */
|
||||
struct si_arg u[MAX_ARGS + 1];
|
||||
|
||||
/* Objects that are used in async buffer request on this context. */
|
||||
struct list_head objects_head;
|
||||
|
||||
int errno;
|
||||
|
||||
/* inbound and outbound buffers. */
|
||||
struct {
|
||||
struct si_buffer msg;
|
||||
phys_addr_t paddr;
|
||||
|
||||
/* TODO. remove after moving to tzmem allocator. */
|
||||
struct qtee_shm shm;
|
||||
} in, out;
|
||||
};
|
||||
|
||||
int si_object_do_invoke(struct si_object_invoke_ctx *oic,
|
||||
struct si_object *object, unsigned long op, struct si_arg u[], int *result);
|
||||
|
||||
/* Reserved Operations. */
|
||||
|
||||
#define SI_OBJECT_OP_METHOD_MASK 0x0000FFFFU
|
||||
#define SI_OBJECT_OP_METHOD_ID(op) ((op) & SI_OBJECT_OP_METHOD_MASK)
|
||||
|
||||
#define SI_OBJECT_OP_RELEASE (SI_OBJECT_OP_METHOD_MASK - 0)
|
||||
#define SI_OBJECT_OP_RETAIN (SI_OBJECT_OP_METHOD_MASK - 1)
|
||||
#define SI_OBJECT_OP_NO_OP (SI_OBJECT_OP_METHOD_MASK - 2)
|
||||
|
||||
struct si_object_operations {
|
||||
void (*release)(struct si_object *object);
|
||||
|
||||
/**
|
||||
* @op_supported:
|
||||
*
|
||||
* Query made to make sure the requested operation is supported. If defined,
|
||||
* it is called before marshaling of the arguments (as optimisation).
|
||||
*/
|
||||
int (*op_supported)(unsigned long op);
|
||||
|
||||
/**
|
||||
* @dispatch:
|
||||
*
|
||||
* Object's dispatch function called on object invocation.
|
||||
* Multiple operations can be dispatched concurrently.
|
||||
*/
|
||||
int (*dispatch)(unsigned int context_id,
|
||||
struct si_object *object, unsigned long op, struct si_arg args[]);
|
||||
|
||||
/**
|
||||
* @notify:
|
||||
*
|
||||
* Notify the change in status of the pervious invocation to the driver;
|
||||
* i.e. transport errors or success (status is zero).
|
||||
*/
|
||||
void (*notify)(unsigned int context_id, struct si_object *object, int status);
|
||||
|
||||
/**
|
||||
* @prepare:
|
||||
*
|
||||
* Called on object of type AT_IO on direct call (or AT_OO on callback
|
||||
* response) to QTEE. The object provider can return (1) a buffer argument
|
||||
* and (2) an object. @args is { { .type == AT_OB }, { .type == AT_OO },
|
||||
* { .type == AT_END } }. On failour, returns SI_OBJECT_OP_NO_OP, otherwise
|
||||
* an operation that provider has done on @object.
|
||||
*/
|
||||
unsigned long (*prepare)(struct si_object *object, struct si_arg args[]);
|
||||
};
|
||||
|
||||
struct si_object {
|
||||
const char *name;
|
||||
struct kref refcount;
|
||||
|
||||
enum si_object_type object_type;
|
||||
union object_info {
|
||||
unsigned long object_ptr;
|
||||
} info;
|
||||
|
||||
struct si_object_operations *ops;
|
||||
|
||||
/* see si_core_async.c. */
|
||||
struct list_head node;
|
||||
|
||||
/* see si_core_wq.c. */
|
||||
struct work_struct work;
|
||||
|
||||
/* Callback for any internal cleanup before the object's release. */
|
||||
void (*release)(struct si_object *object);
|
||||
};
|
||||
|
||||
#define NULL_SI_OBJECT ((struct si_object *)(0))
|
||||
#define ROOT_SI_OBJECT ((struct si_object *)(1))
|
||||
|
||||
static inline enum si_object_type typeof_si_object(struct si_object *object)
|
||||
{
|
||||
if (object == NULL_SI_OBJECT)
|
||||
return SI_OT_NULL;
|
||||
|
||||
if (object == ROOT_SI_OBJECT)
|
||||
return SI_OT_ROOT;
|
||||
|
||||
return object->object_type;
|
||||
}
|
||||
|
||||
static inline const char *si_object_name(struct si_object *object)
|
||||
{
|
||||
if (object == NULL_SI_OBJECT)
|
||||
return "null";
|
||||
|
||||
if (object == ROOT_SI_OBJECT)
|
||||
return "root";
|
||||
|
||||
if (!object->name)
|
||||
return "noname";
|
||||
|
||||
return object->name;
|
||||
}
|
||||
|
||||
#define INIT_NULL_SI_OBJECT { .object_type = SI_OT_NULL }
|
||||
#define SI_OBJECT(name, ...) __SI_OBJECT(name, ##__VA_ARGS__, 1)
|
||||
#define __SI_OBJECT(name, n, ...) struct si_object name[(n)] = { INIT_NULL_SI_OBJECT }
|
||||
|
||||
struct si_object *allocate_si_object(void);
|
||||
void free_si_object(struct si_object *object);
|
||||
|
||||
int init_si_object_user(struct si_object *object, enum si_object_type ot,
|
||||
struct si_object_operations *ops, const char *fmt, ...);
|
||||
|
||||
int get_si_object(struct si_object *object);
|
||||
void put_si_object(struct si_object *object);
|
||||
int get_async_proto_version(void);
|
||||
|
||||
#endif /* _LINUX_SI_OBJECT_H__ */
|
Reference in New Issue
Block a user