Loading Documentation/devicetree/bindings/cnss/icnss.txt +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ Optional properties: uS. - qcom,icnss-vadc: VADC handle for vph_pwr read APIs. - qcom,icnss-adc_tm: VADC handle for vph_pwr notification APIs. - io-channels: IIO channel to monitor for vph_pwr power. - io-channel-names: IIO channel name as per the client name. - qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass - qcom,wlan-msa-fixed-region: phandle, specifier pairs to children of /reserved-memory - qcom,hyp_disabled: Boolean context flag to disable hyperviser Loading drivers/soc/qcom/icnss.c +186 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,9 @@ #include <linux/ipc_logging.h> #include <linux/thread_info.h> #include <linux/uaccess.h> #include <linux/adc-tm-clients.h> #include <linux/iio/consumer.h> #include <dt-bindings/iio/qcom,spmi-vadc.h> #include <linux/etherdevice.h> #include <linux/of.h> #include <linux/of_irq.h> Loading Loading @@ -790,6 +793,136 @@ int icnss_call_driver_uevent(struct icnss_priv *priv, return priv->ops->uevent(&priv->pdev->dev, &uevent_data); } static int icnss_get_phone_power(struct icnss_priv *priv, uint64_t *result_uv) { int ret = 0; int result; if (!priv->channel) { icnss_pr_err("Channel doesn't exists\n"); ret = -EINVAL; goto out; } ret = iio_read_channel_processed(penv->channel, &result); if (ret < 0) { icnss_pr_err("Error reading channel, ret = %d\n", ret); goto out; } *result_uv = (uint64_t) result; out: return ret; } static void icnss_vph_notify(enum adc_tm_state state, void *ctx) { struct icnss_priv *priv = ctx; uint64_t vph_pwr = 0; uint64_t vph_pwr_prev; int ret = 0; bool update = true; if (!priv) { icnss_pr_err("Priv pointer is NULL\n"); return; } vph_pwr_prev = priv->vph_pwr; ret = icnss_get_phone_power(priv, &vph_pwr); if (ret < 0) return; if (vph_pwr < ICNSS_THRESHOLD_LOW) { if (vph_pwr_prev < ICNSS_THRESHOLD_LOW) update = false; priv->vph_monitor_params.state_request = ADC_TM_HIGH_THR_ENABLE; priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_LOW + ICNSS_THRESHOLD_GUARD; priv->vph_monitor_params.low_thr = 0; } else if (vph_pwr > ICNSS_THRESHOLD_HIGH) { if (vph_pwr_prev > ICNSS_THRESHOLD_HIGH) update = false; priv->vph_monitor_params.state_request = ADC_TM_LOW_THR_ENABLE; priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_HIGH - ICNSS_THRESHOLD_GUARD; priv->vph_monitor_params.high_thr = 0; } else { if (vph_pwr_prev > ICNSS_THRESHOLD_LOW && vph_pwr_prev < ICNSS_THRESHOLD_HIGH) update = false; priv->vph_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_ENABLE; priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_LOW; priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_HIGH; } priv->vph_pwr = vph_pwr; if (update) { icnss_send_vbatt_update(priv, vph_pwr); icnss_pr_dbg("set low threshold to %d, high threshold to %d Phone power=%llu\n", priv->vph_monitor_params.low_thr, priv->vph_monitor_params.high_thr, vph_pwr); } ret = adc_tm5_channel_measure(priv->adc_tm_dev, &priv->vph_monitor_params); if (ret) icnss_pr_err("TM channel setup failed %d\n", ret); } static int icnss_setup_vph_monitor(struct icnss_priv *priv) { int ret = 0; if (!priv->adc_tm_dev) { icnss_pr_err("ADC TM handler is NULL\n"); ret = -EINVAL; goto out; } priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_LOW; priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_HIGH; priv->vph_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_ENABLE; priv->vph_monitor_params.channel = ADC_VBAT_SNS; priv->vph_monitor_params.btm_ctx = priv; priv->vph_monitor_params.threshold_notification = &icnss_vph_notify; icnss_pr_dbg("Set low threshold to %d, high threshold to %d\n", priv->vph_monitor_params.low_thr, priv->vph_monitor_params.high_thr); ret = adc_tm5_channel_measure(priv->adc_tm_dev, &priv->vph_monitor_params); if (ret) icnss_pr_err("TM channel setup failed %d\n", ret); out: return ret; } static int icnss_init_vph_monitor(struct icnss_priv *priv) { int ret = 0; ret = icnss_get_phone_power(priv, &priv->vph_pwr); if (ret < 0) goto out; icnss_pr_dbg("Phone power=%llu\n", priv->vph_pwr); icnss_send_vbatt_update(priv, priv->vph_pwr); ret = icnss_setup_vph_monitor(priv); if (ret) goto out; out: return ret; } static int icnss_driver_event_server_arrive(void *data) { int ret = 0; Loading Loading @@ -859,6 +992,9 @@ static int icnss_driver_event_server_arrive(void *data) if (!penv->fw_early_crash_irq) register_early_crash_notifications(&penv->pdev->dev); if (penv->vbatt_supported) icnss_init_vph_monitor(penv); return ret; err_setup_msa: Loading @@ -882,6 +1018,10 @@ static int icnss_driver_event_server_exit(void *data) icnss_clear_server(penv); if (penv->adc_tm_dev && penv->vbatt_supported) adc_tm5_disable_chan_meas(penv->adc_tm_dev, &penv->vph_monitor_params); return 0; } Loading Loading @@ -3045,6 +3185,45 @@ static void icnss_debugfs_destroy(struct icnss_priv *priv) debugfs_remove_recursive(priv->root_dentry); } static int icnss_get_vbatt_info(struct icnss_priv *priv) { struct adc_tm_chip *adc_tm_dev = NULL; struct iio_channel *channel = NULL; int ret = 0; adc_tm_dev = get_adc_tm(&priv->pdev->dev, "icnss"); if (PTR_ERR(adc_tm_dev) == -EPROBE_DEFER) { icnss_pr_err("adc_tm_dev probe defer\n"); return -EPROBE_DEFER; } if (IS_ERR(adc_tm_dev)) { ret = PTR_ERR(adc_tm_dev); icnss_pr_err("Not able to get ADC dev, VBATT monitoring is disabled: %d\n", ret); return ret; } channel = iio_channel_get(&priv->pdev->dev, "icnss"); if (PTR_ERR(channel) == -EPROBE_DEFER) { icnss_pr_err("channel probe defer\n"); return -EPROBE_DEFER; } if (IS_ERR(channel)) { ret = PTR_ERR(channel); icnss_pr_err("Not able to get VADC dev, VBATT monitoring is disabled: %d\n", ret); return ret; } priv->adc_tm_dev = adc_tm_dev; priv->channel = channel; return 0; } static int icnss_probe(struct platform_device *pdev) { int ret = 0; Loading Loading @@ -3074,6 +3253,13 @@ static int icnss_probe(struct platform_device *pdev) priv->vreg_info = icnss_vreg_info; if (of_property_read_bool(pdev->dev.of_node, "qcom,icnss-adc_tm")) { ret = icnss_get_vbatt_info(priv); if (ret == -EPROBE_DEFER) goto out; priv->vbatt_supported = true; } for (i = 0; i < ICNSS_VREG_INFO_SIZE; i++) { ret = icnss_get_vreg_info(dev, &priv->vreg_info[i]); Loading drivers/soc/qcom/icnss_private.h +11 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ #ifndef __ICNSS_PRIVATE_H__ #define __ICNSS_PRIVATE_H__ #include <linux/adc-tm-clients.h> #include <linux/iio/consumer.h> #define icnss_ipc_log_string(_x...) do { \ if (icnss_ipc_log_context) \ ipc_log_string(icnss_ipc_log_context, _x); \ Loading Loading @@ -239,6 +242,9 @@ struct icnss_stats { uint32_t rejuvenate_ack_req; uint32_t rejuvenate_ack_resp; uint32_t rejuvenate_ack_err; uint32_t vbatt_req; uint32_t vbatt_resp; uint32_t vbatt_req_err; }; #define WLFW_MAX_TIMESTAMP_LEN 32 Loading Loading @@ -356,6 +362,11 @@ struct icnss_priv { uint32_t fw_error_fatal_irq; uint32_t fw_early_crash_irq; struct completion unblock_shutdown; struct adc_tm_param vph_monitor_params; struct adc_tm_chip *adc_tm_dev; struct iio_channel *channel; uint64_t vph_pwr; bool vbatt_supported; char function_name[WLFW_FUNCTION_NAME_LEN + 1]; }; Loading drivers/soc/qcom/icnss_qmi.c +70 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <soc/qcom/service-notifier.h> #include "wlan_firmware_service_v01.h" #include "icnss_private.h" #include "icnss_qmi.h" #ifdef CONFIG_ICNSS_DEBUG unsigned long qmi_timeout = 3000; Loading Loading @@ -1324,4 +1325,73 @@ int icnss_send_wlan_disable_to_fw(struct icnss_priv *priv) return wlfw_wlan_mode_send_sync_msg(priv, mode); } int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv) { int ret; struct wlfw_vbatt_req_msg_v01 *req; struct wlfw_vbatt_resp_msg_v01 *resp; struct qmi_txn txn; if (!priv) return -ENODEV; if (test_bit(ICNSS_FW_DOWN, &priv->state)) return -EINVAL; icnss_pr_dbg("Sending Vbatt message, state: 0x%lx\n", priv->state); req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } priv->stats.vbatt_req++; req->voltage_uv = voltage_uv; ret = qmi_txn_init(&priv->qmi, &txn, wlfw_vbatt_resp_msg_v01_ei, resp); if (ret < 0) { icnss_pr_err("Fail to init txn for Vbatt message resp %d\n", ret); goto out; } ret = qmi_send_request(&priv->qmi, NULL, &txn, QMI_WLFW_VBATT_REQ_V01, WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN, wlfw_vbatt_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); icnss_pr_err("Fail to send Vbatt message req %d\n", ret); goto out; } ret = qmi_txn_wait(&txn, WLFW_TIMEOUT); if (ret < 0) { icnss_pr_err("VBATT message resp wait failed with ret %d\n", ret); goto out; } else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { icnss_pr_err("QMI Vbatt message request rejected, result:%d error:%d\n", resp->resp.result, resp->resp.error); ret = -resp->resp.result; goto out; } priv->stats.vbatt_resp++; kfree(resp); kfree(req); return 0; out: kfree(resp); kfree(req); priv->stats.vbatt_req_err++; return ret; } drivers/soc/qcom/icnss_qmi.h +7 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -92,6 +92,11 @@ static inline int icnss_register_fw_service(struct icnss_priv *priv) return 0; } static inline void icnss_unregister_fw_service(struct icnss_priv *priv) {} static inline int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv) { return 0; } #else int wlfw_ind_register_send_sync_msg(struct icnss_priv *priv); Loading Loading @@ -121,6 +126,7 @@ int icnss_send_wlan_enable_to_fw(struct icnss_priv *priv, int icnss_send_wlan_disable_to_fw(struct icnss_priv *priv); int icnss_register_fw_service(struct icnss_priv *priv); void icnss_unregister_fw_service(struct icnss_priv *priv); int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv); #endif #endif /* __ICNSS_QMI_H__*/ Loading
Documentation/devicetree/bindings/cnss/icnss.txt +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ Optional properties: uS. - qcom,icnss-vadc: VADC handle for vph_pwr read APIs. - qcom,icnss-adc_tm: VADC handle for vph_pwr notification APIs. - io-channels: IIO channel to monitor for vph_pwr power. - io-channel-names: IIO channel name as per the client name. - qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass - qcom,wlan-msa-fixed-region: phandle, specifier pairs to children of /reserved-memory - qcom,hyp_disabled: Boolean context flag to disable hyperviser Loading
drivers/soc/qcom/icnss.c +186 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,9 @@ #include <linux/ipc_logging.h> #include <linux/thread_info.h> #include <linux/uaccess.h> #include <linux/adc-tm-clients.h> #include <linux/iio/consumer.h> #include <dt-bindings/iio/qcom,spmi-vadc.h> #include <linux/etherdevice.h> #include <linux/of.h> #include <linux/of_irq.h> Loading Loading @@ -790,6 +793,136 @@ int icnss_call_driver_uevent(struct icnss_priv *priv, return priv->ops->uevent(&priv->pdev->dev, &uevent_data); } static int icnss_get_phone_power(struct icnss_priv *priv, uint64_t *result_uv) { int ret = 0; int result; if (!priv->channel) { icnss_pr_err("Channel doesn't exists\n"); ret = -EINVAL; goto out; } ret = iio_read_channel_processed(penv->channel, &result); if (ret < 0) { icnss_pr_err("Error reading channel, ret = %d\n", ret); goto out; } *result_uv = (uint64_t) result; out: return ret; } static void icnss_vph_notify(enum adc_tm_state state, void *ctx) { struct icnss_priv *priv = ctx; uint64_t vph_pwr = 0; uint64_t vph_pwr_prev; int ret = 0; bool update = true; if (!priv) { icnss_pr_err("Priv pointer is NULL\n"); return; } vph_pwr_prev = priv->vph_pwr; ret = icnss_get_phone_power(priv, &vph_pwr); if (ret < 0) return; if (vph_pwr < ICNSS_THRESHOLD_LOW) { if (vph_pwr_prev < ICNSS_THRESHOLD_LOW) update = false; priv->vph_monitor_params.state_request = ADC_TM_HIGH_THR_ENABLE; priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_LOW + ICNSS_THRESHOLD_GUARD; priv->vph_monitor_params.low_thr = 0; } else if (vph_pwr > ICNSS_THRESHOLD_HIGH) { if (vph_pwr_prev > ICNSS_THRESHOLD_HIGH) update = false; priv->vph_monitor_params.state_request = ADC_TM_LOW_THR_ENABLE; priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_HIGH - ICNSS_THRESHOLD_GUARD; priv->vph_monitor_params.high_thr = 0; } else { if (vph_pwr_prev > ICNSS_THRESHOLD_LOW && vph_pwr_prev < ICNSS_THRESHOLD_HIGH) update = false; priv->vph_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_ENABLE; priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_LOW; priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_HIGH; } priv->vph_pwr = vph_pwr; if (update) { icnss_send_vbatt_update(priv, vph_pwr); icnss_pr_dbg("set low threshold to %d, high threshold to %d Phone power=%llu\n", priv->vph_monitor_params.low_thr, priv->vph_monitor_params.high_thr, vph_pwr); } ret = adc_tm5_channel_measure(priv->adc_tm_dev, &priv->vph_monitor_params); if (ret) icnss_pr_err("TM channel setup failed %d\n", ret); } static int icnss_setup_vph_monitor(struct icnss_priv *priv) { int ret = 0; if (!priv->adc_tm_dev) { icnss_pr_err("ADC TM handler is NULL\n"); ret = -EINVAL; goto out; } priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_LOW; priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_HIGH; priv->vph_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_ENABLE; priv->vph_monitor_params.channel = ADC_VBAT_SNS; priv->vph_monitor_params.btm_ctx = priv; priv->vph_monitor_params.threshold_notification = &icnss_vph_notify; icnss_pr_dbg("Set low threshold to %d, high threshold to %d\n", priv->vph_monitor_params.low_thr, priv->vph_monitor_params.high_thr); ret = adc_tm5_channel_measure(priv->adc_tm_dev, &priv->vph_monitor_params); if (ret) icnss_pr_err("TM channel setup failed %d\n", ret); out: return ret; } static int icnss_init_vph_monitor(struct icnss_priv *priv) { int ret = 0; ret = icnss_get_phone_power(priv, &priv->vph_pwr); if (ret < 0) goto out; icnss_pr_dbg("Phone power=%llu\n", priv->vph_pwr); icnss_send_vbatt_update(priv, priv->vph_pwr); ret = icnss_setup_vph_monitor(priv); if (ret) goto out; out: return ret; } static int icnss_driver_event_server_arrive(void *data) { int ret = 0; Loading Loading @@ -859,6 +992,9 @@ static int icnss_driver_event_server_arrive(void *data) if (!penv->fw_early_crash_irq) register_early_crash_notifications(&penv->pdev->dev); if (penv->vbatt_supported) icnss_init_vph_monitor(penv); return ret; err_setup_msa: Loading @@ -882,6 +1018,10 @@ static int icnss_driver_event_server_exit(void *data) icnss_clear_server(penv); if (penv->adc_tm_dev && penv->vbatt_supported) adc_tm5_disable_chan_meas(penv->adc_tm_dev, &penv->vph_monitor_params); return 0; } Loading Loading @@ -3045,6 +3185,45 @@ static void icnss_debugfs_destroy(struct icnss_priv *priv) debugfs_remove_recursive(priv->root_dentry); } static int icnss_get_vbatt_info(struct icnss_priv *priv) { struct adc_tm_chip *adc_tm_dev = NULL; struct iio_channel *channel = NULL; int ret = 0; adc_tm_dev = get_adc_tm(&priv->pdev->dev, "icnss"); if (PTR_ERR(adc_tm_dev) == -EPROBE_DEFER) { icnss_pr_err("adc_tm_dev probe defer\n"); return -EPROBE_DEFER; } if (IS_ERR(adc_tm_dev)) { ret = PTR_ERR(adc_tm_dev); icnss_pr_err("Not able to get ADC dev, VBATT monitoring is disabled: %d\n", ret); return ret; } channel = iio_channel_get(&priv->pdev->dev, "icnss"); if (PTR_ERR(channel) == -EPROBE_DEFER) { icnss_pr_err("channel probe defer\n"); return -EPROBE_DEFER; } if (IS_ERR(channel)) { ret = PTR_ERR(channel); icnss_pr_err("Not able to get VADC dev, VBATT monitoring is disabled: %d\n", ret); return ret; } priv->adc_tm_dev = adc_tm_dev; priv->channel = channel; return 0; } static int icnss_probe(struct platform_device *pdev) { int ret = 0; Loading Loading @@ -3074,6 +3253,13 @@ static int icnss_probe(struct platform_device *pdev) priv->vreg_info = icnss_vreg_info; if (of_property_read_bool(pdev->dev.of_node, "qcom,icnss-adc_tm")) { ret = icnss_get_vbatt_info(priv); if (ret == -EPROBE_DEFER) goto out; priv->vbatt_supported = true; } for (i = 0; i < ICNSS_VREG_INFO_SIZE; i++) { ret = icnss_get_vreg_info(dev, &priv->vreg_info[i]); Loading
drivers/soc/qcom/icnss_private.h +11 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ #ifndef __ICNSS_PRIVATE_H__ #define __ICNSS_PRIVATE_H__ #include <linux/adc-tm-clients.h> #include <linux/iio/consumer.h> #define icnss_ipc_log_string(_x...) do { \ if (icnss_ipc_log_context) \ ipc_log_string(icnss_ipc_log_context, _x); \ Loading Loading @@ -239,6 +242,9 @@ struct icnss_stats { uint32_t rejuvenate_ack_req; uint32_t rejuvenate_ack_resp; uint32_t rejuvenate_ack_err; uint32_t vbatt_req; uint32_t vbatt_resp; uint32_t vbatt_req_err; }; #define WLFW_MAX_TIMESTAMP_LEN 32 Loading Loading @@ -356,6 +362,11 @@ struct icnss_priv { uint32_t fw_error_fatal_irq; uint32_t fw_early_crash_irq; struct completion unblock_shutdown; struct adc_tm_param vph_monitor_params; struct adc_tm_chip *adc_tm_dev; struct iio_channel *channel; uint64_t vph_pwr; bool vbatt_supported; char function_name[WLFW_FUNCTION_NAME_LEN + 1]; }; Loading
drivers/soc/qcom/icnss_qmi.c +70 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <soc/qcom/service-notifier.h> #include "wlan_firmware_service_v01.h" #include "icnss_private.h" #include "icnss_qmi.h" #ifdef CONFIG_ICNSS_DEBUG unsigned long qmi_timeout = 3000; Loading Loading @@ -1324,4 +1325,73 @@ int icnss_send_wlan_disable_to_fw(struct icnss_priv *priv) return wlfw_wlan_mode_send_sync_msg(priv, mode); } int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv) { int ret; struct wlfw_vbatt_req_msg_v01 *req; struct wlfw_vbatt_resp_msg_v01 *resp; struct qmi_txn txn; if (!priv) return -ENODEV; if (test_bit(ICNSS_FW_DOWN, &priv->state)) return -EINVAL; icnss_pr_dbg("Sending Vbatt message, state: 0x%lx\n", priv->state); req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } priv->stats.vbatt_req++; req->voltage_uv = voltage_uv; ret = qmi_txn_init(&priv->qmi, &txn, wlfw_vbatt_resp_msg_v01_ei, resp); if (ret < 0) { icnss_pr_err("Fail to init txn for Vbatt message resp %d\n", ret); goto out; } ret = qmi_send_request(&priv->qmi, NULL, &txn, QMI_WLFW_VBATT_REQ_V01, WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN, wlfw_vbatt_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); icnss_pr_err("Fail to send Vbatt message req %d\n", ret); goto out; } ret = qmi_txn_wait(&txn, WLFW_TIMEOUT); if (ret < 0) { icnss_pr_err("VBATT message resp wait failed with ret %d\n", ret); goto out; } else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { icnss_pr_err("QMI Vbatt message request rejected, result:%d error:%d\n", resp->resp.result, resp->resp.error); ret = -resp->resp.result; goto out; } priv->stats.vbatt_resp++; kfree(resp); kfree(req); return 0; out: kfree(resp); kfree(req); priv->stats.vbatt_req_err++; return ret; }
drivers/soc/qcom/icnss_qmi.h +7 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -92,6 +92,11 @@ static inline int icnss_register_fw_service(struct icnss_priv *priv) return 0; } static inline void icnss_unregister_fw_service(struct icnss_priv *priv) {} static inline int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv) { return 0; } #else int wlfw_ind_register_send_sync_msg(struct icnss_priv *priv); Loading Loading @@ -121,6 +126,7 @@ int icnss_send_wlan_enable_to_fw(struct icnss_priv *priv, int icnss_send_wlan_disable_to_fw(struct icnss_priv *priv); int icnss_register_fw_service(struct icnss_priv *priv); void icnss_unregister_fw_service(struct icnss_priv *priv); int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv); #endif #endif /* __ICNSS_QMI_H__*/