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.
 -----BEGIN PGP SIGNATURE-----
 
 iQJJBAABCAAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmh1uXIVHGFuZGVyc3Nv
 bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3FZvEQAIoDwwkAySjthXxfuh7ajhVKbT5j
 GMAua5ZdK0jI/SoKKb+y4MSCaJncmB2tScuqxoElVS/4Hjsz/+RSFPIM/TlK9Vab
 6FVI4zC5bdre8153H6JqiucSGyaup1gpwbNB6WGkgHxuX2NcRp9tFa/7bJR0HbO4
 bfXBU10G1f3Cy4QtZG1+Q1wgfMgqDLcsCKVtj/7TifuFN9YW/858lyzZ4xC+oYnS
 WkMz6r98VwA5xasC6vtC0S9KDfXfbpjD3PViaGdrBqHQ7Zn8xWwDKjB6ZuyHyV/l
 NwzmQoNn+jLb5TCepBUvJyekdlICawLnGahJ1UNvA07ASz/Dsu0LpzTxA9bbr2b7
 Towt1ffJ186J6vcrxO67xN3W/fYE9CUgd2U/ISIMLkmbZZ1l2m/PlTVawvkxwlJC
 0DF3UeUhwQgE6aogjyeSUAuOBsPNBxEZhZaKDdjigC8yhyt8Gifiq2W2ar667zbp
 E/IoyJ5dzfO/0DTRsdfWx2hAUMB8to4b5PPbccccuAbNI9Bx4FBa7cXc4atRHRdB
 Uy1v/hVqStRGGwGu0O5Q07Pq+4DVNx0Nrrujlh53jqAh+gdALJgDgVb8Fd7+KjcF
 KhA6rDWO941pDVeyDIIjs+Y95g8xDVKKGuObPkLifcfpKSDkwHVYSM+ksnYwRRKc
 badJm1kmFIqjFZOV
 =jo4F
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmh/+PMACgkQmmx57+YA
 GNnYlhAAqiwfs+qnSYtn9Mwk9qviDns8ptfXlYulwCxTMLGL/hGwXJbURI/wVFsj
 hlqQDDC3iTCkgQBDXN340EIktRsCJ9ElqOiAGEF0Q6PhQ/idK4r2qIM6yNDCzf/F
 5XJFcKpyrJXB3W5MB0Xcbw80RNsh6+fCCDdhwZxNzMaIVG3KfmYHylH7xmk5sg+w
 nkm6g03ovmrYDg++IbKXxPp80neqJu0KmMBXIZlrKTkTNI/kmqmrVsvmeo0gi3nz
 n9wL7WEXjJMSu4TXYgNx2hp0RWGKDcl91ab7QKG+n0+tqcPbkfjdSAfq71mUAbAq
 uHO2WaMfnl2Sxp3xDv83/Dk5qNoL2CDj33sdxWhEmJVg157OKN5qaFzwmALdGEjI
 h3DndeGSQLk7MVNjfQA8W/ZcJgk51Ef6sKqYbRZjiiHKW2tKE1XK/VLceldGMYyI
 F1ngCJTVL/rg6py+ia6l3RqqfDijJ1jUH1Q4Rf6DoH5RqfHcjcEaEUXP6+wvd2NW
 uUKd/OXYItc4T3DJ33d6T94TjRBtl6GyE794u4rRo1frskOScMF85HUOUbGdGobc
 7uE6Xs4AQ20EcolJcuAPi2HBn66q9OFqQPHQgK5jkvw/pb1hKdbIVMiOoMNpdtHz
 oBxBG6ElPsVDrNB1nqQ+POuIqDmtKJ9NJOngGUsy1NRQfCxnT6Q=
 =ZBKF
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Arnd Bergmann 2025-07-22 22:47:47 +02:00
commit 5b8141596b
10 changed files with 253 additions and 27 deletions

View File

@ -200,6 +200,7 @@ properties:
- qcom,kryo385
- qcom,kryo465
- qcom,kryo468
- qcom,kryo470
- qcom,kryo485
- qcom,kryo560
- qcom,kryo570

View File

@ -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

View File

@ -18,6 +18,7 @@ properties:
compatible:
items:
- enum:
- qcom,sm7150-dcc
- qcom,sm8150-dcc
- qcom,sc7280-dcc
- qcom,sc7180-dcc

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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);
}

View File

@ -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[] = {

View File

@ -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