mirror of
https://github.com/commaai/agnos-kernel-sdm845.git
synced 2026-06-08 11:24:51 +08:00
cnss2: Add bus layer
Bus layer is a shim layer for potential buses (PCIe, USB and SDIO) of WLAN devices. It abstracts all the bus related APIs for common files of the driver so that it can help make them bus independent. Change-Id: I06e19a26d34168fe0fcc65229a4519b868cd97c1 Signed-off-by: Yue Ma <yuem@codeaurora.org>
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
c1940edc59
commit
fcf6042ac8
@@ -1,6 +1,7 @@
|
||||
obj-$(CONFIG_CNSS2) += cnss2.o
|
||||
|
||||
cnss2-y := main.o
|
||||
cnss2-y += bus.o
|
||||
cnss2-y += debug.o
|
||||
cnss2-y += pci.o
|
||||
cnss2-y += power.o
|
||||
|
||||
165
drivers/net/wireless/cnss2/bus.c
Normal file
165
drivers/net/wireless/cnss2/bus.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/* Copyright (c) 2018, 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
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "pci.h"
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return CNSS_BUS_NONE;
|
||||
|
||||
if (!dev->bus)
|
||||
return CNSS_BUS_NONE;
|
||||
|
||||
if (memcmp(dev->bus->name, "pci", 3) == 0)
|
||||
return CNSS_BUS_PCI;
|
||||
else
|
||||
return CNSS_BUS_NONE;
|
||||
}
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
|
||||
{
|
||||
switch (device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
return CNSS_BUS_PCI;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
|
||||
return CNSS_BUS_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_init(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_init(plat_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void cnss_bus_deinit(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
cnss_pci_deinit(plat_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_load_m3(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_alloc_fw_mem(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_get_wake_msi(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_force_fw_assert_hdlr(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void cnss_bus_fw_boot_timeout_hdlr(unsigned long data)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data;
|
||||
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_fw_boot_timeout_hdlr(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv, bool in_panic)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_collect_dump_info(plat_priv->bus_priv,
|
||||
in_panic);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
40
drivers/net/wireless/cnss2/bus.h
Normal file
40
drivers/net/wireless/cnss2/bus.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* Copyright (c) 2018, 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
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CNSS_BUS_H
|
||||
#define _CNSS_BUS_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define QCA6174_VENDOR_ID 0x168C
|
||||
#define QCA6174_DEVICE_ID 0x003E
|
||||
#define QCA6174_REV_ID_OFFSET 0x08
|
||||
#define QCA6174_REV3_VERSION 0x5020000
|
||||
#define QCA6174_REV3_2_VERSION 0x5030000
|
||||
#define QCA6290_VENDOR_ID 0x17CB
|
||||
#define QCA6290_DEVICE_ID 0x1100
|
||||
#define QCA6290_EMULATION_VENDOR_ID 0x168C
|
||||
#define QCA6290_EMULATION_DEVICE_ID 0xABCD
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev);
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id);
|
||||
int cnss_bus_init(struct cnss_plat_data *plat_priv);
|
||||
void cnss_bus_deinit(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv);
|
||||
u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv);
|
||||
void cnss_bus_fw_boot_timeout_hdlr(unsigned long data);
|
||||
void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv,
|
||||
bool in_panic);
|
||||
|
||||
#endif /* _CNSS_BUS_H */
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "pci.h"
|
||||
|
||||
@@ -37,7 +38,6 @@
|
||||
#define FW_READY_TIMEOUT 20000
|
||||
#define FW_ASSERT_TIMEOUT 5000
|
||||
#define CNSS_EVENT_PENDING 2989
|
||||
#define WAKE_MSI_NAME "WAKE"
|
||||
|
||||
static struct cnss_plat_data *plat_env;
|
||||
|
||||
@@ -87,20 +87,6 @@ struct cnss_driver_event {
|
||||
void *data;
|
||||
};
|
||||
|
||||
static enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return CNSS_BUS_NONE;
|
||||
|
||||
if (!dev->bus)
|
||||
return CNSS_BUS_NONE;
|
||||
|
||||
if (memcmp(dev->bus->name, "pci", 3) == 0)
|
||||
return CNSS_BUS_PCI;
|
||||
else
|
||||
return CNSS_BUS_NONE;
|
||||
}
|
||||
|
||||
static void cnss_set_plat_priv(struct platform_device *plat_dev,
|
||||
struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
@@ -274,23 +260,6 @@ int cnss_get_platform_cap(struct device *dev, struct cnss_platform_cap *cap)
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_get_platform_cap);
|
||||
|
||||
int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
void *bus_priv = cnss_bus_dev_to_bus_priv(dev);
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
ret = cnss_pci_get_bar_info(bus_priv, &info->va, &info->pa);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_get_soc_info);
|
||||
|
||||
void cnss_request_pm_qos(struct device *dev, u32 qos_val)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
@@ -506,24 +475,6 @@ int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_set_fw_log_mode);
|
||||
|
||||
u32 cnss_get_wake_msi(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
int ret, num_vectors;
|
||||
u32 user_base_data, base_vector;
|
||||
|
||||
ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
WAKE_MSI_NAME, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
|
||||
if (ret) {
|
||||
cnss_pr_err("WAKE MSI is not valid\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return user_base_data;
|
||||
}
|
||||
|
||||
static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -541,7 +492,7 @@ static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = cnss_pci_load_m3(plat_priv->bus_priv);
|
||||
ret = cnss_bus_load_m3(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -1442,7 +1393,6 @@ static const char *cnss_recovery_reason_to_str(enum cnss_recovery_reason reason)
|
||||
static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_recovery_reason reason)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
struct cnss_subsys_info *subsys_info =
|
||||
&plat_priv->subsys_info;
|
||||
|
||||
@@ -1451,11 +1401,6 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
|
||||
if (plat_priv->device_id == QCA6174_DEVICE_ID)
|
||||
goto self_recovery;
|
||||
|
||||
if (plat_priv->driver_ops &&
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state))
|
||||
plat_priv->driver_ops->update_status(pci_priv->pci_dev,
|
||||
CNSS_RECOVERY);
|
||||
|
||||
if (test_bit(SKIP_RECOVERY, &quirks)) {
|
||||
cnss_pr_dbg("Skip device recovery\n");
|
||||
return 0;
|
||||
@@ -1468,7 +1413,7 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
|
||||
break;
|
||||
case CNSS_REASON_RDDM:
|
||||
clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
|
||||
cnss_pci_collect_dump_info(pci_priv, false);
|
||||
cnss_bus_collect_dump_info(plat_priv, false);
|
||||
break;
|
||||
case CNSS_REASON_DEFAULT:
|
||||
case CNSS_REASON_TIMEOUT:
|
||||
@@ -1575,28 +1520,6 @@ void cnss_schedule_recovery(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_schedule_recovery);
|
||||
|
||||
static int cnss_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
int ret;
|
||||
|
||||
ret = cnss_pci_set_mhi_state(plat_priv->bus_priv,
|
||||
CNSS_MHI_TRIGGER_RDDM);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret);
|
||||
cnss_schedule_recovery(&pci_priv->pci_dev->dev,
|
||||
CNSS_REASON_DEFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) {
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cnss_force_fw_assert(struct device *dev)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
@@ -1624,17 +1547,6 @@ int cnss_force_fw_assert(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_force_fw_assert);
|
||||
|
||||
void fw_boot_timeout(unsigned long data)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data;
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
cnss_pr_err("Timeout waiting for FW ready indication!\n");
|
||||
|
||||
cnss_schedule_recovery(&pci_priv->pci_dev->dev,
|
||||
CNSS_REASON_TIMEOUT);
|
||||
}
|
||||
|
||||
static int cnss_register_driver_hdlr(struct cnss_plat_data *plat_priv,
|
||||
void *data)
|
||||
{
|
||||
@@ -1731,7 +1643,7 @@ static void cnss_driver_event_work(struct work_struct *work)
|
||||
ret = cnss_wlfw_server_exit(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_REQUEST_MEM:
|
||||
ret = cnss_pci_alloc_fw_mem(plat_priv->bus_priv);
|
||||
ret = cnss_bus_alloc_fw_mem(plat_priv);
|
||||
if (ret)
|
||||
break;
|
||||
ret = cnss_wlfw_respond_mem_send_sync(plat_priv);
|
||||
@@ -1760,7 +1672,7 @@ static void cnss_driver_event_work(struct work_struct *work)
|
||||
event->data);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
|
||||
ret = cnss_force_fw_assert_hdlr(plat_priv);
|
||||
ret = cnss_bus_force_fw_assert_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_POWER_UP:
|
||||
ret = cnss_power_up_hdlr(plat_priv);
|
||||
@@ -2204,6 +2116,7 @@ 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);
|
||||
cnss_set_plat_priv(plat_dev, plat_priv);
|
||||
platform_set_drvdata(plat_dev, plat_priv);
|
||||
|
||||
@@ -2216,14 +2129,14 @@ static int cnss_probe(struct platform_device *plat_dev)
|
||||
if (ret)
|
||||
goto free_res;
|
||||
|
||||
ret = cnss_pci_init(plat_priv);
|
||||
ret = cnss_bus_init(plat_priv);
|
||||
if (ret)
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
ret = cnss_register_esoc(plat_priv);
|
||||
if (ret)
|
||||
goto deinit_pci;
|
||||
goto deinit_bus;
|
||||
|
||||
ret = cnss_register_bus_scale(plat_priv);
|
||||
if (ret)
|
||||
@@ -2245,8 +2158,8 @@ static int cnss_probe(struct platform_device *plat_dev)
|
||||
if (ret)
|
||||
goto deinit_qmi;
|
||||
|
||||
setup_timer(&plat_priv->fw_boot_timer,
|
||||
fw_boot_timeout, (unsigned long)plat_priv);
|
||||
setup_timer(&plat_priv->fw_boot_timer, cnss_bus_fw_boot_timeout_hdlr,
|
||||
(unsigned long)plat_priv);
|
||||
|
||||
register_pm_notifier(&cnss_pm_notifier);
|
||||
|
||||
@@ -2272,9 +2185,9 @@ unreg_bus_scale:
|
||||
cnss_unregister_bus_scale(plat_priv);
|
||||
unreg_esoc:
|
||||
cnss_unregister_esoc(plat_priv);
|
||||
deinit_pci:
|
||||
deinit_bus:
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &quirks))
|
||||
cnss_pci_deinit(plat_priv);
|
||||
cnss_bus_deinit(plat_priv);
|
||||
power_off:
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &quirks))
|
||||
cnss_power_off_device(plat_priv);
|
||||
@@ -2301,7 +2214,7 @@ static int cnss_remove(struct platform_device *plat_dev)
|
||||
cnss_remove_sysfs(plat_priv);
|
||||
cnss_unregister_bus_scale(plat_priv);
|
||||
cnss_unregister_esoc(plat_priv);
|
||||
cnss_pci_deinit(plat_priv);
|
||||
cnss_bus_deinit(plat_priv);
|
||||
cnss_put_resources(plat_priv);
|
||||
platform_set_drvdata(plat_dev, NULL);
|
||||
plat_env = NULL;
|
||||
|
||||
@@ -173,6 +173,7 @@ struct cnss_pin_connect_result {
|
||||
struct cnss_plat_data {
|
||||
struct platform_device *plat_dev;
|
||||
void *bus_priv;
|
||||
enum cnss_dev_bus_type bus_type;
|
||||
struct cnss_vreg_info *vreg_info;
|
||||
struct cnss_pinctrl_info pinctrl_info;
|
||||
struct cnss_subsys_info subsys_info;
|
||||
@@ -229,6 +230,5 @@ void cnss_unregister_subsys(struct cnss_plat_data *plat_priv);
|
||||
int cnss_register_ramdump(struct cnss_plat_data *plat_priv);
|
||||
void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv);
|
||||
void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv);
|
||||
u32 cnss_get_wake_msi(struct cnss_plat_data *plat_priv);
|
||||
|
||||
#endif /* _CNSS_MAIN_H */
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "pci.h"
|
||||
|
||||
@@ -43,6 +44,10 @@
|
||||
#define MAX_M3_FILE_NAME_LENGTH 13
|
||||
#define DEFAULT_M3_FILE_NAME "m3.bin"
|
||||
|
||||
#define WAKE_MSI_NAME "WAKE"
|
||||
|
||||
#define FW_ASSERT_TIMEOUT 5000
|
||||
|
||||
static DEFINE_SPINLOCK(pci_link_down_lock);
|
||||
|
||||
static unsigned int pci_link_down_panic;
|
||||
@@ -592,18 +597,7 @@ static int cnss_pci_runtime_idle(struct device *dev)
|
||||
|
||||
int cnss_wlan_pm_control(struct device *dev, bool vote)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
struct cnss_pci_data *pci_priv;
|
||||
struct pci_dev *pci_dev;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
pci_priv = plat_priv->bus_priv;
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
pci_dev = pci_priv->pci_dev;
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
|
||||
return msm_pcie_pm_control(vote ? MSM_PCIE_DISABLE_PC :
|
||||
MSM_PCIE_ENABLE_PC,
|
||||
@@ -615,19 +609,17 @@ EXPORT_SYMBOL(cnss_wlan_pm_control);
|
||||
int cnss_auto_suspend(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
struct pci_dev *pci_dev;
|
||||
struct cnss_pci_data *pci_priv;
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
|
||||
struct cnss_plat_data *plat_priv;
|
||||
struct cnss_bus_bw_info *bus_bw_info;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
pci_priv = plat_priv->bus_priv;
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
pci_dev = pci_priv->pci_dev;
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (pci_priv->pci_link_state) {
|
||||
if (cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_SUSPEND)) {
|
||||
@@ -673,19 +665,18 @@ EXPORT_SYMBOL(cnss_auto_suspend);
|
||||
int cnss_auto_resume(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
struct pci_dev *pci_dev;
|
||||
struct cnss_pci_data *pci_priv;
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
|
||||
struct cnss_plat_data *plat_priv;
|
||||
struct cnss_bus_bw_info *bus_bw_info;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
pci_priv = plat_priv->bus_priv;
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
pci_dev = pci_priv->pci_dev;
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (!pci_priv->pci_link_state) {
|
||||
cnss_pr_dbg("Resuming PCI link\n");
|
||||
if (cnss_set_pci_link(pci_priv, PCI_LINK_UP)) {
|
||||
@@ -830,18 +821,59 @@ static void cnss_pci_free_m3_mem(struct cnss_pci_data *pci_priv)
|
||||
m3_mem->size = 0;
|
||||
}
|
||||
|
||||
int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va,
|
||||
phys_addr_t *pa)
|
||||
int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret;
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
*va = pci_priv->bar;
|
||||
*pa = pci_resource_start(pci_priv->pci_dev, PCI_BAR_NUM);
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_TRIGGER_RDDM);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret);
|
||||
cnss_schedule_recovery(&pci_priv->pci_dev->dev,
|
||||
CNSS_REASON_DEFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) {
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
if (!pci_priv)
|
||||
return;
|
||||
|
||||
cnss_pr_err("Timeout waiting for FW ready indication\n");
|
||||
|
||||
cnss_schedule_recovery(&pci_priv->pci_dev->dev,
|
||||
CNSS_REASON_TIMEOUT);
|
||||
}
|
||||
|
||||
int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
info->va = pci_priv->bar;
|
||||
info->pa = pci_resource_start(pci_priv->pci_dev, PCI_BAR_NUM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_get_soc_info);
|
||||
|
||||
static struct cnss_msi_config msi_config = {
|
||||
.total_vectors = 32,
|
||||
.total_users = 4,
|
||||
@@ -927,7 +959,7 @@ int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
|
||||
int *num_vectors, u32 *user_base_data,
|
||||
u32 *base_vector)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = dev_get_drvdata(dev);
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
|
||||
struct cnss_msi_config *msi_config;
|
||||
int idx;
|
||||
|
||||
@@ -986,6 +1018,25 @@ void cnss_get_msi_address(struct device *dev, u32 *msi_addr_low,
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_get_msi_address);
|
||||
|
||||
u32 cnss_pci_get_wake_msi(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret, num_vectors;
|
||||
u32 user_base_data, base_vector;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
WAKE_MSI_NAME, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
if (ret) {
|
||||
cnss_pr_err("WAKE MSI is not valid\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return user_base_data;
|
||||
}
|
||||
|
||||
static int cnss_pci_enable_bus(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -21,16 +21,6 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define QCA6174_VENDOR_ID 0x168C
|
||||
#define QCA6174_DEVICE_ID 0x003E
|
||||
#define QCA6174_REV_ID_OFFSET 0x08
|
||||
#define QCA6174_REV3_VERSION 0x5020000
|
||||
#define QCA6174_REV3_2_VERSION 0x5030000
|
||||
#define QCA6290_VENDOR_ID 0x17CB
|
||||
#define QCA6290_DEVICE_ID 0x1100
|
||||
#define QCA6290_EMULATION_VENDOR_ID 0x168C
|
||||
#define QCA6290_EMULATION_DEVICE_ID 0xABCD
|
||||
|
||||
enum cnss_mhi_state {
|
||||
CNSS_MHI_INIT,
|
||||
CNSS_MHI_DEINIT,
|
||||
@@ -130,8 +120,6 @@ int cnss_pci_init(struct cnss_plat_data *plat_priv);
|
||||
void cnss_pci_deinit(struct cnss_plat_data *plat_priv);
|
||||
int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_load_m3(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va,
|
||||
phys_addr_t *pa);
|
||||
int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,
|
||||
enum cnss_mhi_state state);
|
||||
int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv);
|
||||
@@ -139,5 +127,8 @@ void cnss_pci_stop_mhi(struct cnss_pci_data *pci_priv);
|
||||
void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic);
|
||||
void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pm_request_resume(struct cnss_pci_data *pci_priv);
|
||||
u32 cnss_pci_get_wake_msi(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv);
|
||||
void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv);
|
||||
|
||||
#endif /* _CNSS_PCI_H */
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
#include <linux/qmi_encdec.h>
|
||||
#include <soc/qcom/msm_qmi_interface.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "main.h"
|
||||
#include "qmi.h"
|
||||
|
||||
#define WLFW_SERVICE_INS_ID_V01 1
|
||||
@@ -163,7 +164,7 @@ static int cnss_wlfw_host_cap_send_sync(struct cnss_plat_data *plat_priv)
|
||||
req.num_clients = daemon_support ? 2 : 1;
|
||||
cnss_pr_dbg("Number of clients is %d\n", req.num_clients);
|
||||
|
||||
req.wake_msi = cnss_get_wake_msi(plat_priv);
|
||||
req.wake_msi = cnss_bus_get_wake_irq(plat_priv);
|
||||
if (req.wake_msi) {
|
||||
cnss_pr_dbg("WAKE MSI base data is %d\n", req.wake_msi);
|
||||
req.wake_msi_valid = 1;
|
||||
|
||||
Reference in New Issue
Block a user