mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
Merge "cnss2: Add sysfs entry for system shutdown"
This commit is contained in:
commit
3c948ad14e
6 changed files with 292 additions and 6 deletions
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
|
@ -642,6 +642,13 @@ int cnss_idle_restart(struct device *dev)
|
|||
timeout = cnss_get_boot_timeout(dev);
|
||||
|
||||
reinit_completion(&plat_priv->power_up_complete);
|
||||
|
||||
if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wait_for_completion_timeout(&plat_priv->power_up_complete,
|
||||
msecs_to_jiffies(timeout) << 2);
|
||||
if (!ret) {
|
||||
|
|
@ -1918,6 +1925,23 @@ static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv)
|
|||
icc_put(bus_bw_info->cnss_path);
|
||||
}
|
||||
|
||||
static ssize_t shutdown_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);
|
||||
|
||||
if (plat_priv) {
|
||||
set_bit(CNSS_IN_REBOOT, &plat_priv->driver_state);
|
||||
del_timer(&plat_priv->fw_boot_timer);
|
||||
complete_all(&plat_priv->power_up_complete);
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Received shutdown notification\n");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t fs_ready_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
|
|
@ -1961,18 +1985,55 @@ static ssize_t fs_ready_store(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute shutdown_attribute = __ATTR_WO(shutdown);
|
||||
static DEVICE_ATTR_WO(fs_ready);
|
||||
|
||||
static int cnss_create_shutdown_sysfs(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
plat_priv->shutdown_kobj = kobject_create_and_add("shutdown_wlan",
|
||||
kernel_kobj);
|
||||
if (!plat_priv->shutdown_kobj) {
|
||||
cnss_pr_err("Failed to create shutdown_wlan kernel object\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = sysfs_create_file(plat_priv->shutdown_kobj,
|
||||
&shutdown_attribute.attr);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to create sysfs shutdown file, err = %d\n",
|
||||
ret);
|
||||
kobject_put(plat_priv->shutdown_kobj);
|
||||
plat_priv->shutdown_kobj = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_remove_shutdown_sysfs(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (plat_priv->shutdown_kobj) {
|
||||
sysfs_remove_file(plat_priv->shutdown_kobj,
|
||||
&shutdown_attribute.attr);
|
||||
kobject_put(plat_priv->shutdown_kobj);
|
||||
plat_priv->shutdown_kobj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int cnss_create_sysfs(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = device_create_file(&plat_priv->plat_dev->dev, &dev_attr_fs_ready);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to create device file, err = %d\n", ret);
|
||||
cnss_pr_err("Failed to create device fs_ready file, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cnss_create_shutdown_sysfs(plat_priv);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
|
|
@ -1980,6 +2041,7 @@ out:
|
|||
|
||||
static void cnss_remove_sysfs(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
cnss_remove_shutdown_sysfs(plat_priv);
|
||||
device_remove_file(&plat_priv->plat_dev->dev, &dev_attr_fs_ready);
|
||||
}
|
||||
|
||||
|
|
@ -2070,6 +2132,17 @@ static void cnss_init_control_params(struct cnss_plat_data *plat_priv)
|
|||
plat_priv->ctrl_params.time_sync_period = CNSS_TIME_SYNC_PERIOD_DEFAULT;
|
||||
}
|
||||
|
||||
static void cnss_get_wlaon_pwr_ctrl_info(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
|
||||
plat_priv->set_wlaon_pwr_ctrl =
|
||||
of_property_read_bool(dev->of_node, "qcom,set-wlaon-pwr-ctrl");
|
||||
|
||||
cnss_pr_dbg("set_wlaon_pwr_ctrl is %d\n",
|
||||
plat_priv->set_wlaon_pwr_ctrl);
|
||||
}
|
||||
|
||||
static const struct platform_device_id cnss_platform_id_table[] = {
|
||||
{ .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, },
|
||||
{ .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
|
||||
|
|
@ -2095,6 +2168,13 @@ static const struct of_device_id cnss_of_match_table[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, cnss_of_match_table);
|
||||
|
||||
static inline bool
|
||||
cnss_use_nv_mac(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return of_property_read_bool(plat_priv->plat_dev->dev.of_node,
|
||||
"use-nv-mac");
|
||||
}
|
||||
|
||||
static int cnss_probe(struct platform_device *plat_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -2127,11 +2207,13 @@ static int cnss_probe(struct platform_device *plat_dev)
|
|||
plat_priv->plat_dev = plat_dev;
|
||||
plat_priv->device_id = device_id->driver_data;
|
||||
plat_priv->bus_type = cnss_get_bus_type(plat_priv->device_id);
|
||||
plat_priv->use_nv_mac = cnss_use_nv_mac(plat_priv);
|
||||
cnss_set_plat_priv(plat_dev, plat_priv);
|
||||
platform_set_drvdata(plat_dev, plat_priv);
|
||||
INIT_LIST_HEAD(&plat_priv->vreg_list);
|
||||
INIT_LIST_HEAD(&plat_priv->clk_list);
|
||||
|
||||
cnss_get_wlaon_pwr_ctrl_info(plat_priv);
|
||||
cnss_get_cpr_info(plat_priv);
|
||||
cnss_init_control_params(plat_priv);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef _CNSS_MAIN_H
|
||||
#define _CNSS_MAIN_H
|
||||
|
|
@ -372,6 +372,9 @@ struct cnss_plat_data {
|
|||
u64 dynamic_feature;
|
||||
void *get_info_cb_ctx;
|
||||
int (*get_info_cb)(void *ctx, void *event, int event_len);
|
||||
u8 use_nv_mac;
|
||||
u8 set_wlaon_pwr_ctrl;
|
||||
struct kobject *shutdown_kobj;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_QCOM
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ static DEFINE_SPINLOCK(time_sync_lock);
|
|||
#define MHI_TIMEOUT_OVERWRITE_MS (plat_priv->ctrl_params.mhi_timeout)
|
||||
#define MHI_M2_TIMEOUT_MS (plat_priv->ctrl_params.mhi_m2_timeout)
|
||||
|
||||
#define WLAON_PWR_CTRL_SHUTDOWN_DELAY_MIN_US 1000
|
||||
#define WLAON_PWR_CTRL_SHUTDOWN_DELAY_MAX_US 2000
|
||||
|
||||
#define FORCE_WAKE_DELAY_MIN_US 4000
|
||||
#define FORCE_WAKE_DELAY_MAX_US 6000
|
||||
#define FORCE_WAKE_DELAY_TIMEOUT_US 60000
|
||||
|
|
@ -480,6 +483,7 @@ static int cnss_pci_force_wake_get(struct cnss_pci_data *pci_priv)
|
|||
|
||||
if (cnss_pci_is_device_awake(dev) != true) {
|
||||
cnss_pr_err("Timed out to request force wake\n");
|
||||
cnss_pci_force_wake_release(dev);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
|
@ -1131,6 +1135,62 @@ static void cnss_pci_deinit_mhi(struct cnss_pci_data *pci_priv)
|
|||
cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_DEINIT);
|
||||
}
|
||||
|
||||
static void cnss_pci_set_wlaon_pwr_ctrl(struct cnss_pci_data *pci_priv,
|
||||
bool set_vddd4blow, bool set_shutdown,
|
||||
bool do_force_wake)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
if (!plat_priv->set_wlaon_pwr_ctrl)
|
||||
return;
|
||||
|
||||
if (do_force_wake)
|
||||
if (cnss_pci_force_wake_get(pci_priv))
|
||||
return;
|
||||
|
||||
ret = cnss_pci_reg_read(pci_priv, QCA6390_WLAON_QFPROM_PWR_CTRL_REG,
|
||||
&val);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to read register offset 0x%x, err = %d\n",
|
||||
QCA6390_WLAON_QFPROM_PWR_CTRL_REG, ret);
|
||||
goto force_wake_put;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Read register offset 0x%x, val = 0x%x\n",
|
||||
QCA6390_WLAON_QFPROM_PWR_CTRL_REG, val);
|
||||
|
||||
if (set_vddd4blow)
|
||||
val |= QFPROM_PWR_CTRL_VDD4BLOW_SW_EN_MASK;
|
||||
else
|
||||
val &= ~QFPROM_PWR_CTRL_VDD4BLOW_SW_EN_MASK;
|
||||
|
||||
if (set_shutdown)
|
||||
val |= QFPROM_PWR_CTRL_SHUTDOWN_EN_MASK;
|
||||
else
|
||||
val &= ~QFPROM_PWR_CTRL_SHUTDOWN_EN_MASK;
|
||||
|
||||
ret = cnss_pci_reg_write(pci_priv, QCA6390_WLAON_QFPROM_PWR_CTRL_REG,
|
||||
val);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to write register offset 0x%x, err = %d\n",
|
||||
QCA6390_WLAON_QFPROM_PWR_CTRL_REG, ret);
|
||||
goto force_wake_put;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Write val 0x%x to register offset 0x%x\n", val,
|
||||
QCA6390_WLAON_QFPROM_PWR_CTRL_REG);
|
||||
|
||||
if (set_shutdown)
|
||||
usleep_range(WLAON_PWR_CTRL_SHUTDOWN_DELAY_MIN_US,
|
||||
WLAON_PWR_CTRL_SHUTDOWN_DELAY_MAX_US);
|
||||
|
||||
force_wake_put:
|
||||
if (do_force_wake)
|
||||
cnss_pci_force_wake_put(pci_priv);
|
||||
}
|
||||
|
||||
static int cnss_pci_get_device_timestamp(struct cnss_pci_data *pci_priv,
|
||||
u64 *time_us)
|
||||
{
|
||||
|
|
@ -1671,6 +1731,7 @@ retry:
|
|||
goto power_off;
|
||||
}
|
||||
|
||||
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false);
|
||||
timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev);
|
||||
|
||||
ret = cnss_pci_start_mhi(pci_priv);
|
||||
|
|
@ -1705,6 +1766,7 @@ retry:
|
|||
return 0;
|
||||
|
||||
stop_mhi:
|
||||
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, true, true);
|
||||
cnss_pci_power_off_mhi(pci_priv);
|
||||
cnss_suspend_pci_link(pci_priv);
|
||||
cnss_pci_deinit_mhi(pci_priv);
|
||||
|
|
@ -1718,6 +1780,7 @@ static int cnss_qca6290_shutdown(struct cnss_pci_data *pci_priv)
|
|||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
int do_force_wake = true;
|
||||
|
||||
cnss_pci_pm_runtime_resume(pci_priv);
|
||||
|
||||
|
|
@ -1744,6 +1807,10 @@ static int cnss_qca6290_shutdown(struct cnss_pci_data *pci_priv)
|
|||
goto skip_power_off;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state))
|
||||
do_force_wake = false;
|
||||
|
||||
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, true, do_force_wake);
|
||||
cnss_pci_power_off_mhi(pci_priv);
|
||||
ret = cnss_suspend_pci_link(pci_priv);
|
||||
if (ret)
|
||||
|
|
@ -4113,6 +4180,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
|
|||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false);
|
||||
timer_setup(&pci_priv->dev_rddm_timer,
|
||||
cnss_dev_rddm_timeout_hdlr, 0);
|
||||
INIT_DELAYED_WORK(&pci_priv->time_sync_work,
|
||||
|
|
@ -4127,11 +4195,10 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
|
|||
goto disable_bus;
|
||||
}
|
||||
cnss_pci_get_link_status(pci_priv);
|
||||
|
||||
cnss_pci_config_regs(pci_priv);
|
||||
|
||||
if (EMULATION_HW)
|
||||
break;
|
||||
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, true, false);
|
||||
ret = cnss_suspend_pci_link(pci_priv);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to suspend PCI link, err = %d\n",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@
|
|||
|
||||
#define QMI_WLFW_MAX_RECV_BUF_SIZE SZ_8K
|
||||
|
||||
#define QMI_WLFW_MAC_READY_TIMEOUT_MS 50
|
||||
#define QMI_WLFW_MAC_READY_MAX_RETRY 200
|
||||
|
||||
static char *cnss_qmi_mode_to_str(enum cnss_driver_mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
|
|
@ -692,6 +695,131 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv,
|
||||
u8 *mac, u32 mac_len)
|
||||
{
|
||||
struct wlfw_mac_addr_req_msg_v01 *req;
|
||||
struct wlfw_mac_addr_resp_msg_v01 *resp;
|
||||
struct qmi_txn txn;
|
||||
int ret;
|
||||
u8 is_query;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
/* NULL mac && zero mac_len means querying the status of MAC in FW */
|
||||
if ((mac && mac_len != QMI_WLFW_MAC_ADDR_SIZE_V01) ||
|
||||
(!mac && mac_len != 0))
|
||||
return -EINVAL;
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
resp = kzalloc(sizeof(*resp), GFP_KERNEL);
|
||||
if (!resp) {
|
||||
kfree(req);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn,
|
||||
wlfw_mac_addr_resp_msg_v01_ei, resp);
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("Failed to initialize txn for mac req, err: %d\n",
|
||||
ret);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
is_query = !mac;
|
||||
if (!is_query) {
|
||||
/* DO NOT print this for mac query, that might be too many */
|
||||
cnss_pr_dbg("Sending WLAN mac req [%pM], state: 0x%lx\n",
|
||||
mac, plat_priv->driver_state);
|
||||
memcpy(req->mac_addr, mac, mac_len);
|
||||
|
||||
/* 0 - query status of wlfw MAC; 1 - set wlfw MAC */
|
||||
req->mac_addr_valid = 1;
|
||||
}
|
||||
|
||||
ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn,
|
||||
QMI_WLFW_MAC_ADDR_REQ_V01,
|
||||
WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN,
|
||||
wlfw_mac_addr_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
cnss_pr_err("Failed to send mac req, err: %d\n", ret);
|
||||
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF);
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("Failed to wait for resp of mac req, err: %d\n",
|
||||
ret);
|
||||
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
cnss_pr_err("WLAN mac req failed, result: %d, err: %d\n",
|
||||
resp->resp.result);
|
||||
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp->resp.error != QMI_ERR_NONE_V01) {
|
||||
ret = ((resp->resp.error == QMI_ERR_NETWORK_NOT_READY_V01 &&
|
||||
is_query) ? -EAGAIN : -EIO);
|
||||
if (ret != -EAGAIN)
|
||||
cnss_pr_err("Got error resp for mac req, err: %d\n",
|
||||
resp->resp.error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("WLAN mac req completed\n");
|
||||
|
||||
out:
|
||||
kfree(req);
|
||||
kfree(resp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_wait_for_wlfw_mac_ready(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret, retry = 0;
|
||||
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
cnss_pr_dbg("Checking wlfw mac, state: 0x%lx\n",
|
||||
plat_priv->driver_state);
|
||||
do {
|
||||
/* query the current status of WLAN MAC */
|
||||
ret = cnss_wlfw_wlan_mac_req_send_sync(plat_priv, NULL, 0);
|
||||
if (!ret) {
|
||||
cnss_pr_dbg("wlfw mac is ready\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != -EAGAIN) {
|
||||
cnss_pr_err("failed to query wlfw mac, error: %d\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if (++retry >= QMI_WLFW_MAC_READY_MAX_RETRY) {
|
||||
cnss_pr_err("Timeout to wait for wlfw mac ready\n");
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(QMI_WLFW_MAC_READY_TIMEOUT_MS);
|
||||
} while (true);
|
||||
}
|
||||
|
||||
int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_driver_mode mode)
|
||||
{
|
||||
|
|
@ -703,6 +831,9 @@ int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv,
|
|||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (mode == CNSS_MISSION && plat_priv->use_nv_mac)
|
||||
cnss_wait_for_wlfw_mac_ready(plat_priv);
|
||||
|
||||
cnss_pr_dbg("Sending mode message, mode: %s(%d), state: 0x%lx\n",
|
||||
cnss_qmi_mode_to_str(mode), mode, plat_priv->driver_state);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2019, The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef _CNSS_REG_H
|
||||
#define _CNSS_REG_H
|
||||
|
|
@ -204,6 +204,8 @@
|
|||
#define QCA6390_WLAON_WL_CLK_CNTL_KDF_REG 0x1F80314
|
||||
#define QCA6390_WLAON_WL_CLK_CNTL_PMU_HFRC_REG 0x1F80318
|
||||
#define QCA6390_WLAON_QFPROM_PWR_CTRL_REG 0x1F8031C
|
||||
#define QFPROM_PWR_CTRL_VDD4BLOW_SW_EN_MASK 0x4
|
||||
#define QFPROM_PWR_CTRL_SHUTDOWN_EN_MASK 0x1
|
||||
#define QCA6390_WLAON_DLY_CONFIG 0x1F80400
|
||||
#define QCA6390_WLAON_WLAON_Q6_IRQ_REG 0x1F80404
|
||||
#define QCA6390_WLAON_PCIE_INTF_SW_CFG_REG 0x1F80408
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ struct qmi_elem_info {
|
|||
#define QMI_ERR_INTERNAL_V01 3
|
||||
#define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 5
|
||||
#define QMI_ERR_INVALID_ID_V01 41
|
||||
#define QMI_ERR_NETWORK_NOT_READY_V01 53
|
||||
#define QMI_ERR_ENCODING_V01 58
|
||||
#define QMI_ERR_DISABLED_V01 69
|
||||
#define QMI_ERR_INCOMPATIBLE_STATE_V01 90
|
||||
|
|
|
|||
Loading…
Reference in a new issue