diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2025-07-22 22:47:47 +0200 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2025-07-22 22:47:47 +0200 |
| commit | 5b8141596b06fba7313cdfbd5f589649d7fde662 (patch) | |
| tree | b8d09174dabd87d79eb8aeff2eb3ade043bc1925 | |
| parent | 9841d92754d0f3846977a39844c3395ee2463381 (diff) | |
| parent | 9f35ab0e53ccbea57bb9cbad8065e0406d516195 (diff) | |
Merge tag 'qcom-drivers-for-6.17' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers
Qualcomm driver updates for v6.17
Perform input validation in the MDT loader, as this was not properly
done in the non-remoteproc cases.
Fix endian issues in the QMI encoder/decoder.
Support reading DDR statistic using the Qualcomm stats driver.
Add support for reading TME firmware details to the socinfo driver.
Document the Kryo 470 CPU, and add SM7150 to the DCC to DeviceTree
bindings.
* tag 'qcom-drivers-for-6.17' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
soc: qcom: mdt_loader: Fix error return values in mdt_header_valid()
dt-bindings: sram: qcom,imem: Add a number of missing compatibles
dt-bindings: arm: cpus: Add Kryo 470 CPUs
dt-bindings: sram: qcom,imem: Add the SM7150 compatible
dt-bindings: soc: qcom: aoss-qmp: Add the SM7150 compatible
dt-bindings: soc: qcom,dcc: Add the SM7150 compatible
soc: qcom: socinfo: Add support to retrieve TME build details
soc: qcom: fix endianness for QMI header
soc: qcom: QMI encoding/decoding for big endian
dt-bindings: soc: qcom: add qcom,qcs615-imem compatible
soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
soc: qcom: qcom_stats: Add support to read DDR statistic
soc: qcom: mdt_loader: Actually use the e_phoff
soc: qcom: mdt_loader: Rename mdt_phdr_valid()
soc: qcom: mdt_loader: Ensure we don't read past the ELF header
Link: https://lore.kernel.org/r/20250715021454.14516-1-andersson@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
| -rw-r--r-- | Documentation/devicetree/bindings/arm/cpus.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/sram/qcom,imem.yaml | 15 | ||||
| -rw-r--r-- | drivers/soc/qcom/mdt_loader.c | 63 | ||||
| -rw-r--r-- | drivers/soc/qcom/qcom_stats.c | 133 | ||||
| -rw-r--r-- | drivers/soc/qcom/qmi_encdec.c | 52 | ||||
| -rw-r--r-- | drivers/soc/qcom/qmi_interface.c | 6 | ||||
| -rw-r--r-- | drivers/soc/qcom/socinfo.c | 2 | ||||
| -rw-r--r-- | include/linux/soc/qcom/qmi.h | 6 |
10 files changed, 253 insertions, 27 deletions
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 2e9ab9583005..5bd517befb68 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -200,6 +200,7 @@ properties: - qcom,kryo385 - qcom,kryo465 - qcom,kryo468 + - qcom,kryo470 - qcom,kryo485 - qcom,kryo560 - qcom,kryo570 diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml index 41fbbe059d80..b1a786b838d5 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml @@ -38,6 +38,7 @@ properties: - qcom,sdx75-aoss-qmp - qcom,sdm845-aoss-qmp - qcom,sm6350-aoss-qmp + - qcom,sm7150-aoss-qmp - qcom,sm8150-aoss-qmp - qcom,sm8250-aoss-qmp - qcom,sm8350-aoss-qmp diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml index ce7e20dd22c9..fdc6fc17ed71 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml @@ -18,6 +18,7 @@ properties: compatible: items: - enum: + - qcom,sm7150-dcc - qcom,sm8150-dcc - qcom,sc7280-dcc - qcom,sc7180-dcc diff --git a/Documentation/devicetree/bindings/sram/qcom,imem.yaml b/Documentation/devicetree/bindings/sram/qcom,imem.yaml index 2711f90d9664..72d35e30c439 100644 --- a/Documentation/devicetree/bindings/sram/qcom,imem.yaml +++ b/Documentation/devicetree/bindings/sram/qcom,imem.yaml @@ -22,17 +22,32 @@ properties: - qcom,msm8974-imem - qcom,msm8976-imem - qcom,qcs404-imem + - qcom,qcs615-imem - qcom,qcs8300-imem - qcom,qdu1000-imem - qcom,sa8775p-imem + - qcom,sar2130p-imem - qcom,sc7180-imem - qcom,sc7280-imem + - qcom,sc8280xp-imem - qcom,sdm630-imem - qcom,sdm845-imem - qcom,sdx55-imem - qcom,sdx65-imem + - qcom,sdx75-imem + - qcom,sm6115-imem + - qcom,sm6125-imem + - qcom,sm6350-imem - qcom,sm6375-imem + - qcom,sm7150-imem + - qcom,sm8150-imem + - qcom,sm8250-imem + - qcom,sm8350-imem - qcom,sm8450-imem + - qcom,sm8550-imem + - qcom,sm8650-imem + - qcom,sm8750-imem + - qcom,x1e80100-imem - const: syscon - const: simple-mfd diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index b2c0fb55d4ae..0ca268bdf1f8 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -18,7 +18,38 @@ #include <linux/slab.h> #include <linux/soc/qcom/mdt_loader.h> -static bool mdt_phdr_valid(const struct elf32_phdr *phdr) +static bool mdt_header_valid(const struct firmware *fw) +{ + const struct elf32_hdr *ehdr; + size_t phend; + size_t shend; + + if (fw->size < sizeof(*ehdr)) + return false; + + ehdr = (struct elf32_hdr *)fw->data; + + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) + return false; + + if (ehdr->e_phentsize != sizeof(struct elf32_phdr)) + return false; + + phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff); + if (phend > fw->size) + return false; + + if (ehdr->e_shentsize != sizeof(struct elf32_shdr)) + return false; + + shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff); + if (shend > fw->size) + return false; + + return true; +} + +static bool mdt_phdr_loadable(const struct elf32_phdr *phdr) { if (phdr->p_type != PT_LOAD) return false; @@ -82,13 +113,16 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw) phys_addr_t max_addr = 0; int i; + if (!mdt_header_valid(fw)) + return -EINVAL; + ehdr = (struct elf32_hdr *)fw->data; - phdrs = (struct elf32_phdr *)(ehdr + 1); + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { phdr = &phdrs[i]; - if (!mdt_phdr_valid(phdr)) + if (!mdt_phdr_loadable(phdr)) continue; if (phdr->p_paddr < min_addr) @@ -134,8 +168,11 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, ssize_t ret; void *data; + if (!mdt_header_valid(fw)) + return ERR_PTR(-EINVAL); + ehdr = (struct elf32_hdr *)fw->data; - phdrs = (struct elf32_phdr *)(ehdr + 1); + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); if (ehdr->e_phnum < 2) return ERR_PTR(-EINVAL); @@ -214,13 +251,16 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, int ret; int i; + if (!mdt_header_valid(fw)) + return -EINVAL; + ehdr = (struct elf32_hdr *)fw->data; - phdrs = (struct elf32_phdr *)(ehdr + 1); + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { phdr = &phdrs[i]; - if (!mdt_phdr_valid(phdr)) + if (!mdt_phdr_loadable(phdr)) continue; if (phdr->p_flags & QCOM_MDT_RELOCATABLE) @@ -270,7 +310,7 @@ static bool qcom_mdt_bins_are_split(const struct firmware *fw, const char *fw_na int i; ehdr = (struct elf32_hdr *)fw->data; - phdrs = (struct elf32_phdr *)(ehdr + 1); + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { /* @@ -310,14 +350,17 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, if (!fw || !mem_region || !mem_phys || !mem_size) return -EINVAL; + if (!mdt_header_valid(fw)) + return -EINVAL; + is_split = qcom_mdt_bins_are_split(fw, fw_name); ehdr = (struct elf32_hdr *)fw->data; - phdrs = (struct elf32_phdr *)(ehdr + 1); + phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { phdr = &phdrs[i]; - if (!mdt_phdr_valid(phdr)) + if (!mdt_phdr_loadable(phdr)) continue; if (phdr->p_flags & QCOM_MDT_RELOCATABLE) @@ -344,7 +387,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, for (i = 0; i < ehdr->e_phnum; i++) { phdr = &phdrs[i]; - if (!mdt_phdr_valid(phdr)) + if (!mdt_phdr_loadable(phdr)) continue; offset = phdr->p_paddr - mem_reloc; diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c index 5de99cf59b9f..2e380faf9080 100644 --- a/drivers/soc/qcom/qcom_stats.c +++ b/drivers/soc/qcom/qcom_stats.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved. */ +#include <linux/bitfield.h> #include <linux/debugfs.h> #include <linux/device.h> #include <linux/io.h> @@ -11,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/seq_file.h> +#include <linux/soc/qcom/qcom_aoss.h> #include <linux/soc/qcom/smem.h> #include <clocksource/arm_arch_timer.h> @@ -24,6 +27,19 @@ #define ACCUMULATED_OFFSET 0x18 #define CLIENT_VOTES_OFFSET 0x20 +#define DDR_STATS_MAGIC_KEY 0xA1157A75 +#define DDR_STATS_MAX_NUM_MODES 20 +#define DDR_STATS_MAGIC_KEY_ADDR 0x0 +#define DDR_STATS_NUM_MODES_ADDR 0x4 +#define DDR_STATS_ENTRY_START_ADDR 0x8 + +#define DDR_STATS_CP_IDX(data) FIELD_GET(GENMASK(4, 0), data) +#define DDR_STATS_LPM_NAME(data) FIELD_GET(GENMASK(7, 0), data) +#define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data) +#define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data) + +static struct qmp *qcom_stats_qmp; + struct subsystem_data { const char *name; u32 smem_item; @@ -48,12 +64,19 @@ static const struct subsystem_data subsystems[] = { struct stats_config { size_t stats_offset; + size_t ddr_stats_offset; size_t num_records; bool appended_stats_avail; bool dynamic_offset; bool subsystem_stats_in_smem; }; +struct ddr_stats_entry { + u32 name; + u32 count; + u64 duration; +}; + struct stats_data { bool appended_stats_avail; void __iomem *base; @@ -122,8 +145,101 @@ static int qcom_soc_sleep_stats_show(struct seq_file *s, void *unused) return 0; } +static void qcom_ddr_stats_print(struct seq_file *s, struct ddr_stats_entry *data) +{ + u32 cp_idx; + + /* + * DDR statistic have two different types of details encoded. + * (1) DDR LPM Stats + * (2) DDR Frequency Stats + * + * The name field have details like which type of DDR stat (bits 8:15) + * along with other details as explained below + * + * In case of DDR LPM stat, name field will be encoded as, + * Bits - Meaning + * 0:7 - DDR LPM name, can be of 0xd4, 0xd3, 0x11 and 0xd0. + * 8:15 - 0x0 (indicates its a LPM stat) + * 16:31 - Unused + * + * In case of DDR FREQ stats, name field will be encoded as, + * Bits - Meaning + * 0:4 - DDR Clock plan index (CP IDX) + * 5:7 - Unused + * 8:15 - 0x1 (indicates its Freq stat) + * 16:31 - Frequency value in Mhz + */ + switch (DDR_STATS_TYPE(data->name)) { + case 0: + seq_printf(s, "DDR LPM Stat Name:0x%lx\tcount:%u\tDuration (ticks):%llu\n", + DDR_STATS_LPM_NAME(data->name), data->count, data->duration); + break; + case 1: + if (!data->count || !DDR_STATS_FREQ(data->name)) + return; + + cp_idx = DDR_STATS_CP_IDX(data->name); + seq_printf(s, "DDR Freq %luMhz:\tCP IDX:%u\tcount:%u\tDuration (ticks):%llu\n", + DDR_STATS_FREQ(data->name), cp_idx, data->count, data->duration); + break; + } +} + +static int qcom_ddr_stats_show(struct seq_file *s, void *d) +{ + struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES]; + void __iomem *reg = (void __iomem *)s->private; + u32 entry_count; + int i, ret; + + entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR); + if (entry_count > DDR_STATS_MAX_NUM_MODES) + return -EINVAL; + + if (qcom_stats_qmp) { + /* + * Recent SoCs (SM8450 onwards) do not have duration field + * populated from boot up onwards for both DDR LPM Stats + * and DDR Frequency Stats. + * + * Send QMP message to Always on processor which will + * populate duration field into MSG RAM area. + * + * Sent every time to read latest data. + */ + ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}"); + if (ret) + return ret; + } + + reg += DDR_STATS_ENTRY_START_ADDR; + memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count); + + for (i = 0; i < entry_count; i++) + qcom_ddr_stats_print(s, &data[i]); + + return 0; +} + DEFINE_SHOW_ATTRIBUTE(qcom_soc_sleep_stats); DEFINE_SHOW_ATTRIBUTE(qcom_subsystem_sleep_stats); +DEFINE_SHOW_ATTRIBUTE(qcom_ddr_stats); + +static void qcom_create_ddr_stat_files(struct dentry *root, void __iomem *reg, + const struct stats_config *config) +{ + u32 key; + + if (!config->ddr_stats_offset) + return; + + key = readl_relaxed(reg + config->ddr_stats_offset + DDR_STATS_MAGIC_KEY_ADDR); + if (key == DDR_STATS_MAGIC_KEY) + debugfs_create_file("ddr_stats", 0400, root, + (__force void *)reg + config->ddr_stats_offset, + &qcom_ddr_stats_fops); +} static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *reg, struct stats_data *d, @@ -207,11 +323,27 @@ static int qcom_stats_probe(struct platform_device *pdev) for (i = 0; i < config->num_records; i++) d[i].appended_stats_avail = config->appended_stats_avail; + /* + * QMP is used for DDR stats syncing to MSG RAM for recent SoCs (SM8450 onwards). + * The prior SoCs do not need QMP handle as the required stats are already present + * in MSG RAM, provided the DDR_STATS_MAGIC_KEY matches. + */ + qcom_stats_qmp = qmp_get(&pdev->dev); + if (IS_ERR(qcom_stats_qmp)) { + /* We ignore error if QMP is not defined/needed */ + if (!of_property_present(pdev->dev.of_node, "qcom,qmp")) + qcom_stats_qmp = NULL; + else if (PTR_ERR(qcom_stats_qmp) == -EPROBE_DEFER) + return -EPROBE_DEFER; + else + return PTR_ERR(qcom_stats_qmp); + } root = debugfs_create_dir("qcom_stats", NULL); qcom_create_subsystem_stat_files(root, config); qcom_create_soc_sleep_stat_files(root, reg, d, config); + qcom_create_ddr_stat_files(root, reg, config); platform_set_drvdata(pdev, root); @@ -254,6 +386,7 @@ static const struct stats_config rpmh_data_sdm845 = { static const struct stats_config rpmh_data = { .stats_offset = 0x48, + .ddr_stats_offset = 0xb8, .num_records = 3, .appended_stats_avail = false, .dynamic_offset = false, diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c index bb09eff85cff..7660a960fb45 100644 --- a/drivers/soc/qcom/qmi_encdec.c +++ b/drivers/soc/qcom/qmi_encdec.c @@ -304,6 +304,8 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf, const void *buf_src; int encode_tlv = 0; int rc; + u8 val8; + u16 val16; if (!ei_array) return 0; @@ -338,7 +340,6 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf, break; case QMI_DATA_LEN: - memcpy(&data_len_value, buf_src, temp_ei->elem_size); data_len_sz = temp_ei->elem_size == sizeof(u8) ? sizeof(u8) : sizeof(u16); /* Check to avoid out of range buffer access */ @@ -348,8 +349,17 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf, __func__); return -ETOOSMALL; } - rc = qmi_encode_basic_elem(buf_dst, &data_len_value, - 1, data_len_sz); + if (data_len_sz == sizeof(u8)) { + val8 = *(u8 *)buf_src; + data_len_value = (u32)val8; + rc = qmi_encode_basic_elem(buf_dst, &val8, + 1, data_len_sz); + } else { + val16 = *(u16 *)buf_src; + data_len_value = (u32)le16_to_cpu(val16); + rc = qmi_encode_basic_elem(buf_dst, &val16, + 1, data_len_sz); + } UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst, encoded_bytes, tlv_len, encode_tlv, rc); @@ -523,14 +533,23 @@ static int qmi_decode_string_elem(const struct qmi_elem_info *ei_array, u32 string_len = 0; u32 string_len_sz = 0; const struct qmi_elem_info *temp_ei = ei_array; + u8 val8; + u16 val16; if (dec_level == 1) { string_len = tlv_len; } else { string_len_sz = temp_ei->elem_len <= U8_MAX ? sizeof(u8) : sizeof(u16); - rc = qmi_decode_basic_elem(&string_len, buf_src, - 1, string_len_sz); + if (string_len_sz == sizeof(u8)) { + rc = qmi_decode_basic_elem(&val8, buf_src, + 1, string_len_sz); + string_len = (u32)val8; + } else { + rc = qmi_decode_basic_elem(&val16, buf_src, + 1, string_len_sz); + string_len = (u32)val16; + } decoded_bytes += rc; } @@ -604,6 +623,9 @@ static int qmi_decode(const struct qmi_elem_info *ei_array, void *out_c_struct, u32 decoded_bytes = 0; const void *buf_src = in_buf; int rc; + u8 val8; + u16 val16; + u32 val32; while (decoded_bytes < in_buf_len) { if (dec_level >= 2 && temp_ei->data_type == QMI_EOTI) @@ -642,9 +664,17 @@ static int qmi_decode(const struct qmi_elem_info *ei_array, void *out_c_struct, if (temp_ei->data_type == QMI_DATA_LEN) { data_len_sz = temp_ei->elem_size == sizeof(u8) ? sizeof(u8) : sizeof(u16); - rc = qmi_decode_basic_elem(&data_len_value, buf_src, - 1, data_len_sz); - memcpy(buf_dst, &data_len_value, sizeof(u32)); + if (data_len_sz == sizeof(u8)) { + rc = qmi_decode_basic_elem(&val8, buf_src, + 1, data_len_sz); + data_len_value = (u32)val8; + } else { + rc = qmi_decode_basic_elem(&val16, buf_src, + 1, data_len_sz); + data_len_value = (u32)val16; + } + val32 = cpu_to_le32(data_len_value); + memcpy(buf_dst, &val32, sizeof(u32)); temp_ei = temp_ei + 1; buf_dst = out_c_struct + temp_ei->offset; tlv_len -= data_len_sz; @@ -746,9 +776,9 @@ void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, hdr = msg; hdr->type = type; - hdr->txn_id = txn_id; - hdr->msg_id = msg_id; - hdr->msg_len = msglen; + hdr->txn_id = cpu_to_le16(txn_id); + hdr->msg_id = cpu_to_le16(msg_id); + hdr->msg_len = cpu_to_le16(msglen); *len = sizeof(*hdr) + msglen; diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c index bc6d6379d8b1..6500f863aae5 100644 --- a/drivers/soc/qcom/qmi_interface.c +++ b/drivers/soc/qcom/qmi_interface.c @@ -400,7 +400,7 @@ static void qmi_invoke_handler(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, for (handler = qmi->handlers; handler->fn; handler++) { if (handler->type == hdr->type && - handler->msg_id == hdr->msg_id) + handler->msg_id == le16_to_cpu(hdr->msg_id)) break; } @@ -488,7 +488,7 @@ static void qmi_handle_message(struct qmi_handle *qmi, /* If this is a response, find the matching transaction handle */ if (hdr->type == QMI_RESPONSE) { mutex_lock(&qmi->txn_lock); - txn = idr_find(&qmi->txns, hdr->txn_id); + txn = idr_find(&qmi->txns, le16_to_cpu(hdr->txn_id)); /* Ignore unexpected responses */ if (!txn) { @@ -514,7 +514,7 @@ static void qmi_handle_message(struct qmi_handle *qmi, } else { /* Create a txn based on the txn_id of the incoming message */ memset(&tmp_txn, 0, sizeof(tmp_txn)); - tmp_txn.id = hdr->txn_id; + tmp_txn.id = le16_to_cpu(hdr->txn_id); qmi_invoke_handler(qmi, sq, &tmp_txn, buf, len); } diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 8c4147737c35..391380820f08 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -48,6 +48,7 @@ #define SMEM_IMAGE_TABLE_CDSP1_INDEX 19 #define SMEM_IMAGE_TABLE_GPDSP_INDEX 20 #define SMEM_IMAGE_TABLE_GPDSP1_INDEX 21 +#define SMEM_IMAGE_TABLE_TME_INDEX 28 #define SMEM_IMAGE_VERSION_TABLE 469 /* @@ -67,6 +68,7 @@ static const char *const socinfo_image_names[] = { [SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1", [SMEM_IMAGE_TABLE_GPDSP_INDEX] = "gpdsp", [SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1", + [SMEM_IMAGE_TABLE_TME_INDEX] = "tme", }; static const char *const pmic_models[] = { diff --git a/include/linux/soc/qcom/qmi.h b/include/linux/soc/qcom/qmi.h index 469e02d2aa0d..291cdc7ef49c 100644 --- a/include/linux/soc/qcom/qmi.h +++ b/include/linux/soc/qcom/qmi.h @@ -24,9 +24,9 @@ struct socket; */ struct qmi_header { u8 type; - u16 txn_id; - u16 msg_id; - u16 msg_len; + __le16 txn_id; + __le16 msg_id; + __le16 msg_len; } __packed; #define QMI_REQUEST 0 |
