Merge "cnss2: Refactor PCIe bus related code"
This commit is contained in:
commit
741e5a2f47
6 changed files with 799 additions and 552 deletions
|
@ -41,6 +41,38 @@ enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
|
|||
}
|
||||
}
|
||||
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
switch (cnss_get_dev_bus_type(dev)) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_get_pci_priv(to_pci_dev(dev));
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev)
|
||||
{
|
||||
void *bus_priv;
|
||||
|
||||
if (!dev)
|
||||
return cnss_get_plat_priv(NULL);
|
||||
|
||||
bus_priv = cnss_bus_dev_to_bus_priv(dev);
|
||||
if (!bus_priv)
|
||||
return NULL;
|
||||
|
||||
switch (cnss_get_dev_bus_type(dev)) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_priv_to_plat_priv(bus_priv);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_init(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
|
@ -150,11 +182,19 @@ void cnss_bus_fw_boot_timeout_hdlr(unsigned long data)
|
|||
|
||||
void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
ret = cnss_pci_set_mhi_state(plat_priv->bus_priv,
|
||||
CNSS_MHI_RDDM);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to complete RDDM, err = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
return cnss_pci_collect_dump_info(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
|
@ -162,3 +202,155 @@ void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_call_driver_probe(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_call_driver_probe(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_call_driver_remove(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_call_driver_remove(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_dev_powerup(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_dev_powerup(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_dev_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_dev_shutdown(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_dev_crash_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_dev_crash_shutdown(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_dev_ramdump(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_dev_ramdump(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_register_driver_hdlr(struct cnss_plat_data *plat_priv, void *data)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_register_driver_hdlr(plat_priv->bus_priv, data);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_unregister_driver_hdlr(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
|
||||
int modem_current_status)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_call_driver_modem_status(plat_priv->bus_priv,
|
||||
modem_current_status);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_recovery_update_status(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_recovery_update_status(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
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);
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev);
|
||||
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev);
|
||||
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);
|
||||
|
@ -35,5 +37,15 @@ 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);
|
||||
|
||||
int cnss_bus_call_driver_probe(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_call_driver_remove(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_dev_powerup(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_dev_shutdown(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_dev_crash_shutdown(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_dev_ramdump(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_register_driver_hdlr(struct cnss_plat_data *plat_priv, void *data);
|
||||
int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
|
||||
int modem_current_status);
|
||||
int cnss_bus_recovery_update_status(struct cnss_plat_data *plat_priv);
|
||||
#endif /* _CNSS_BUS_H */
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "main.h"
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "pci.h"
|
||||
|
||||
#define CNSS_DUMP_FORMAT_VER 0x11
|
||||
#define CNSS_DUMP_FORMAT_VER_V2 0x22
|
||||
|
@ -55,13 +54,6 @@ module_param(enable_waltest, bool, 0600);
|
|||
MODULE_PARM_DESC(enable_waltest, "Enable to handle firmware waltest");
|
||||
#endif
|
||||
|
||||
enum cnss_debug_quirks {
|
||||
LINK_DOWN_SELF_RECOVERY,
|
||||
SKIP_DEVICE_BOOT,
|
||||
USE_CORE_ONLY_FW,
|
||||
SKIP_RECOVERY,
|
||||
};
|
||||
|
||||
unsigned long quirks;
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
module_param(quirks, ulong, 0600);
|
||||
|
@ -93,44 +85,11 @@ static void cnss_set_plat_priv(struct platform_device *plat_dev,
|
|||
plat_env = plat_priv;
|
||||
}
|
||||
|
||||
static struct cnss_plat_data *cnss_get_plat_priv(struct platform_device
|
||||
*plat_dev)
|
||||
struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev)
|
||||
{
|
||||
return plat_env;
|
||||
}
|
||||
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
switch (cnss_get_dev_bus_type(dev)) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_get_pci_priv(to_pci_dev(dev));
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev)
|
||||
{
|
||||
void *bus_priv;
|
||||
|
||||
if (!dev)
|
||||
return cnss_get_plat_priv(NULL);
|
||||
|
||||
bus_priv = cnss_bus_dev_to_bus_priv(dev);
|
||||
if (!bus_priv)
|
||||
return NULL;
|
||||
|
||||
switch (cnss_get_dev_bus_type(dev)) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_priv_to_plat_priv(bus_priv);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int cnss_pm_notify(struct notifier_block *b,
|
||||
unsigned long event, void *p)
|
||||
{
|
||||
|
@ -475,6 +434,16 @@ int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
|
|||
}
|
||||
EXPORT_SYMBOL(cnss_set_fw_log_mode);
|
||||
|
||||
unsigned long *cnss_get_debug_quirks(void)
|
||||
{
|
||||
return &quirks;
|
||||
}
|
||||
|
||||
bool *cnss_get_qmi_bypass(void)
|
||||
{
|
||||
return &qmi_bypass;
|
||||
}
|
||||
|
||||
static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -505,79 +474,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
if (test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
cnss_pr_dbg("Skip driver probe\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!plat_priv->driver_ops) {
|
||||
cnss_pr_err("driver_ops is NULL\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
|
||||
ret = plat_priv->driver_ops->reinit(pci_priv->pci_dev,
|
||||
pci_priv->pci_device_id);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to reinit host driver, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
} else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) {
|
||||
ret = plat_priv->driver_ops->probe(pci_priv->pci_dev,
|
||||
pci_priv->pci_device_id);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to probe host driver, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
|
||||
set_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_driver_call_remove(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Skip driver remove\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!plat_priv->driver_ops) {
|
||||
cnss_pr_err("driver_ops is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
|
||||
plat_priv->driver_ops->shutdown(pci_priv->pci_dev);
|
||||
} else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
|
||||
plat_priv->driver_ops->remove(pci_priv->pci_dev);
|
||||
clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -601,7 +497,7 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
QMI_WLFW_CALIBRATION_V01);
|
||||
} else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
|
||||
ret = cnss_driver_call_probe(plat_priv);
|
||||
ret = cnss_bus_call_driver_probe(plat_priv);
|
||||
} else {
|
||||
complete(&plat_priv->power_up_complete);
|
||||
}
|
||||
|
@ -614,9 +510,7 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
return 0;
|
||||
|
||||
shutdown:
|
||||
cnss_pci_stop_mhi(plat_priv->bus_priv);
|
||||
cnss_suspend_pci_link(plat_priv->bus_priv);
|
||||
cnss_power_off_device(plat_priv);
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
|
||||
clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
|
||||
|
@ -788,44 +682,6 @@ int cnss_power_down(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(cnss_power_down);
|
||||
|
||||
int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (plat_priv->driver_ops) {
|
||||
cnss_pr_err("Driver has already registered!\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
ret = cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_REGISTER_DRIVER,
|
||||
CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
|
||||
driver_ops);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_wlan_register_driver);
|
||||
|
||||
void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
|
||||
CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_wlan_unregister_driver);
|
||||
|
||||
static int cnss_get_resources(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -857,13 +713,11 @@ static int cnss_modem_notifier_nb(struct notifier_block *nb,
|
|||
{
|
||||
struct cnss_plat_data *plat_priv =
|
||||
container_of(nb, struct cnss_plat_data, modem_nb);
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
struct cnss_esoc_info *esoc_info;
|
||||
struct cnss_wlan_driver *driver_ops;
|
||||
|
||||
cnss_pr_dbg("Modem notifier: event %lu\n", code);
|
||||
|
||||
if (!pci_priv)
|
||||
if (!plat_priv)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
esoc_info = &plat_priv->esoc_info;
|
||||
|
@ -875,13 +729,10 @@ static int cnss_modem_notifier_nb(struct notifier_block *nb,
|
|||
else
|
||||
return NOTIFY_DONE;
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
if (!driver_ops || !driver_ops->modem_status)
|
||||
if (!cnss_bus_call_driver_modem_status(plat_priv,
|
||||
esoc_info->modem_current_status))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
driver_ops->modem_status(pci_priv->pci_dev,
|
||||
esoc_info->modem_current_status);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
@ -955,246 +806,6 @@ static void cnss_unregister_esoc(struct cnss_plat_data *plat_priv)
|
|||
devm_unregister_esoc_client(dev, esoc_info->esoc_desc);
|
||||
}
|
||||
|
||||
static int cnss_qca6174_powerup(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = cnss_power_on_device(plat_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to power on device, err = %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = cnss_resume_pci_link(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
ret = cnss_driver_call_probe(plat_priv);
|
||||
if (ret)
|
||||
goto suspend_link;
|
||||
|
||||
return 0;
|
||||
suspend_link:
|
||||
cnss_suspend_pci_link(pci_priv);
|
||||
power_off:
|
||||
cnss_power_off_device(plat_priv);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
cnss_pm_request_resume(pci_priv);
|
||||
|
||||
cnss_driver_call_remove(plat_priv);
|
||||
|
||||
cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
|
||||
CNSS_BUS_WIDTH_NONE);
|
||||
cnss_pci_set_monitor_wake_intr(pci_priv, false);
|
||||
cnss_pci_set_auto_suspended(pci_priv, 0);
|
||||
|
||||
ret = cnss_suspend_pci_link(pci_priv);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
|
||||
|
||||
cnss_power_off_device(plat_priv);
|
||||
|
||||
clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_qca6174_crash_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
if (!plat_priv->driver_ops)
|
||||
return;
|
||||
|
||||
plat_priv->driver_ops->crash_shutdown(pci_priv->pci_dev);
|
||||
}
|
||||
|
||||
static int cnss_qca6290_powerup(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
unsigned int timeout;
|
||||
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (plat_priv->ramdump_info_v2.dump_data_valid ||
|
||||
test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
|
||||
cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_DEINIT);
|
||||
cnss_pci_clear_dump_info(pci_priv);
|
||||
}
|
||||
|
||||
ret = cnss_power_on_device(plat_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to power on device, err = %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = cnss_resume_pci_link(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
timeout = cnss_get_qmi_timeout();
|
||||
|
||||
ret = cnss_pci_start_mhi(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to start MHI, err = %d\n", ret);
|
||||
if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state) &&
|
||||
!pci_priv->pci_link_down_ind && timeout)
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(timeout >> 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_bit(USE_CORE_ONLY_FW, &quirks)) {
|
||||
clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnss_set_pin_connect_status(plat_priv);
|
||||
|
||||
if (qmi_bypass) {
|
||||
ret = cnss_driver_call_probe(plat_priv);
|
||||
if (ret)
|
||||
goto stop_mhi;
|
||||
} else if (timeout) {
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(timeout << 1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
stop_mhi:
|
||||
cnss_pci_stop_mhi(pci_priv);
|
||||
cnss_suspend_pci_link(pci_priv);
|
||||
power_off:
|
||||
cnss_power_off_device(plat_priv);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qca6290_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
cnss_pm_request_resume(pci_priv);
|
||||
|
||||
cnss_driver_call_remove(plat_priv);
|
||||
|
||||
cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
|
||||
CNSS_BUS_WIDTH_NONE);
|
||||
cnss_pci_set_monitor_wake_intr(pci_priv, false);
|
||||
cnss_pci_set_auto_suspended(pci_priv, 0);
|
||||
|
||||
cnss_pci_stop_mhi(pci_priv);
|
||||
|
||||
ret = cnss_suspend_pci_link(pci_priv);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
|
||||
|
||||
cnss_power_off_device(plat_priv);
|
||||
|
||||
clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_qca6290_crash_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
|
||||
int ret = 0;
|
||||
|
||||
cnss_pr_dbg("Crash shutdown with driver_state 0x%lx\n",
|
||||
plat_priv->driver_state);
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Ignore crash shutdown\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RDDM_KERNEL_PANIC);
|
||||
if (ret) {
|
||||
cnss_pr_err("Fail to complete RDDM, err = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
cnss_pci_collect_dump_info(pci_priv);
|
||||
}
|
||||
|
||||
static int cnss_powerup(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_qca6174_powerup(plat_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
ret = cnss_qca6290_powerup(plat_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%lx\n",
|
||||
plat_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_shutdown(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_qca6174_shutdown(plat_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
ret = cnss_qca6290_shutdown(plat_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%lx\n",
|
||||
plat_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_subsys_powerup(const struct subsys_desc *subsys_desc)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
@ -1215,7 +826,7 @@ static int cnss_subsys_powerup(const struct subsys_desc *subsys_desc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return cnss_powerup(plat_priv);
|
||||
return cnss_bus_dev_powerup(plat_priv);
|
||||
}
|
||||
|
||||
static int cnss_subsys_shutdown(const struct subsys_desc *subsys_desc,
|
||||
|
@ -1239,68 +850,12 @@ static int cnss_subsys_shutdown(const struct subsys_desc *subsys_desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return cnss_shutdown(plat_priv);
|
||||
}
|
||||
|
||||
static int cnss_qca6290_ramdump(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
|
||||
struct cnss_dump_data *dump_data = &info_v2->dump_data;
|
||||
struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr;
|
||||
struct ramdump_segment *ramdump_segs, *s;
|
||||
int i, ret = 0;
|
||||
|
||||
if (!info_v2->dump_data_valid ||
|
||||
dump_data->nentries == 0)
|
||||
return 0;
|
||||
|
||||
ramdump_segs = kcalloc(dump_data->nentries,
|
||||
sizeof(*ramdump_segs),
|
||||
GFP_KERNEL);
|
||||
if (!ramdump_segs)
|
||||
return -ENOMEM;
|
||||
|
||||
s = ramdump_segs;
|
||||
for (i = 0; i < dump_data->nentries; i++) {
|
||||
s->address = dump_seg->address;
|
||||
s->v_address = dump_seg->v_address;
|
||||
s->size = dump_seg->size;
|
||||
s++;
|
||||
dump_seg++;
|
||||
}
|
||||
|
||||
ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs,
|
||||
dump_data->nentries);
|
||||
kfree(ramdump_segs);
|
||||
|
||||
cnss_pci_set_mhi_state(plat_priv->bus_priv, CNSS_MHI_DEINIT);
|
||||
cnss_pci_clear_dump_info(plat_priv->bus_priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qca6174_ramdump(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_ramdump_info *ramdump_info;
|
||||
struct ramdump_segment segment;
|
||||
|
||||
ramdump_info = &plat_priv->ramdump_info;
|
||||
if (!ramdump_info->ramdump_size)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&segment, 0, sizeof(segment));
|
||||
segment.v_address = ramdump_info->ramdump_va;
|
||||
segment.size = ramdump_info->ramdump_size;
|
||||
ret = do_ramdump(ramdump_info->ramdump_dev, &segment, 1);
|
||||
|
||||
return ret;
|
||||
return cnss_bus_dev_shutdown(plat_priv);
|
||||
}
|
||||
|
||||
static int cnss_subsys_ramdump(int enable,
|
||||
const struct subsys_desc *subsys_desc)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = dev_get_drvdata(subsys_desc->dev);
|
||||
|
||||
if (!plat_priv) {
|
||||
|
@ -1311,21 +866,7 @@ static int cnss_subsys_ramdump(int enable,
|
|||
if (!enable)
|
||||
return 0;
|
||||
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_qca6174_ramdump(plat_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
ret = cnss_qca6290_ramdump(plat_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%lx\n",
|
||||
plat_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cnss_bus_dev_ramdump(plat_priv);
|
||||
}
|
||||
|
||||
void *cnss_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
|
||||
|
@ -1368,19 +909,7 @@ static void cnss_subsys_crash_shutdown(const struct subsys_desc *subsys_desc)
|
|||
cnss_pr_err("plat_priv is NULL!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
cnss_qca6174_crash_shutdown(plat_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
cnss_qca6290_crash_shutdown(plat_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%lx\n",
|
||||
plat_priv->device_id);
|
||||
}
|
||||
cnss_bus_dev_crash_shutdown(plat_priv);
|
||||
}
|
||||
|
||||
static const char *cnss_recovery_reason_to_str(enum cnss_recovery_reason reason)
|
||||
|
@ -1402,20 +931,15 @@ 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;
|
||||
int ret = 0;
|
||||
|
||||
plat_priv->recovery_count++;
|
||||
|
||||
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);
|
||||
cnss_bus_recovery_update_status(plat_priv);
|
||||
|
||||
if (test_bit(SKIP_RECOVERY, &quirks)) {
|
||||
cnss_pr_dbg("Skip device recovery\n");
|
||||
|
@ -1429,11 +953,6 @@ 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);
|
||||
ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RDDM);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to complete RDDM, err = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
cnss_bus_collect_dump_info(plat_priv);
|
||||
break;
|
||||
case CNSS_REASON_DEFAULT:
|
||||
|
@ -1454,8 +973,8 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
|
|||
return 0;
|
||||
|
||||
self_recovery:
|
||||
cnss_shutdown(plat_priv);
|
||||
cnss_powerup(plat_priv);
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
cnss_bus_dev_powerup(plat_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1568,38 +1087,12 @@ int cnss_force_fw_assert(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(cnss_force_fw_assert);
|
||||
|
||||
static int cnss_register_driver_hdlr(struct cnss_plat_data *plat_priv,
|
||||
void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
set_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
|
||||
plat_priv->driver_ops = data;
|
||||
|
||||
ret = cnss_powerup(plat_priv);
|
||||
if (ret) {
|
||||
clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
|
||||
plat_priv->driver_ops = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
|
||||
cnss_shutdown(plat_priv);
|
||||
plat_priv->driver_ops = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
set_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
ret = cnss_powerup(plat_priv);
|
||||
ret = cnss_bus_dev_powerup(plat_priv);
|
||||
if (ret)
|
||||
clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
|
||||
|
@ -1610,7 +1103,7 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
|
|||
{
|
||||
plat_priv->cal_done = true;
|
||||
cnss_wlfw_wlan_mode_send_sync(plat_priv, QMI_WLFW_OFF_V01);
|
||||
cnss_shutdown(plat_priv);
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
|
||||
return 0;
|
||||
|
@ -1618,12 +1111,12 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
|
|||
|
||||
static int cnss_power_up_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return cnss_powerup(plat_priv);
|
||||
return cnss_bus_dev_powerup(plat_priv);
|
||||
}
|
||||
|
||||
static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
cnss_shutdown(plat_priv);
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1682,11 +1175,11 @@ static void cnss_driver_event_work(struct work_struct *work)
|
|||
ret = cnss_cold_boot_cal_done_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_REGISTER_DRIVER:
|
||||
ret = cnss_register_driver_hdlr(plat_priv,
|
||||
event->data);
|
||||
ret = cnss_bus_register_driver_hdlr(plat_priv,
|
||||
event->data);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
|
||||
ret = cnss_unregister_driver_hdlr(plat_priv);
|
||||
ret = cnss_bus_unregister_driver_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_RECOVERY:
|
||||
ret = cnss_driver_recovery_hdlr(plat_priv,
|
||||
|
|
|
@ -164,6 +164,13 @@ struct cnss_pin_connect_result {
|
|||
u32 host_pin_result;
|
||||
};
|
||||
|
||||
enum cnss_debug_quirks {
|
||||
LINK_DOWN_SELF_RECOVERY,
|
||||
SKIP_DEVICE_BOOT,
|
||||
USE_CORE_ONLY_FW,
|
||||
SKIP_RECOVERY,
|
||||
};
|
||||
|
||||
struct cnss_plat_data {
|
||||
struct platform_device *plat_dev;
|
||||
void *bus_priv;
|
||||
|
@ -179,7 +186,6 @@ struct cnss_plat_data {
|
|||
struct cnss_platform_cap cap;
|
||||
struct pm_qos_request qos_request;
|
||||
unsigned long device_id;
|
||||
struct cnss_wlan_driver *driver_ops;
|
||||
enum cnss_driver_status driver_status;
|
||||
u32 recovery_count;
|
||||
unsigned long driver_state;
|
||||
|
@ -210,8 +216,8 @@ struct cnss_plat_data {
|
|||
bool cal_done;
|
||||
};
|
||||
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev);
|
||||
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev);
|
||||
struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev);
|
||||
unsigned long *cnss_get_debug_quirks(void);
|
||||
int cnss_driver_event_post(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_driver_event_type type,
|
||||
u32 flags, void *data);
|
||||
|
@ -238,5 +244,5 @@ 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);
|
||||
|
||||
bool *cnss_get_qmi_bypass(void);
|
||||
#endif /* _CNSS_MAIN_H */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <soc/qcom/ramdump.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "bus.h"
|
||||
|
@ -234,6 +235,532 @@ static int cnss_set_pci_link(struct cnss_pci_data *pci_priv, bool link_up)
|
|||
}
|
||||
#endif /* CONFIG_PCI_MSM */
|
||||
|
||||
int cnss_pci_recovery_update_status(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
|
||||
if (pci_priv->driver_ops &&
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state))
|
||||
pci_priv->driver_ops->update_status(pci_priv->pci_dev,
|
||||
CNSS_RECOVERY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cnss_pci_call_driver_probe(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
|
||||
if (test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
cnss_pr_dbg("Skip driver probe\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pci_priv->driver_ops) {
|
||||
cnss_pr_err("driver_ops is NULL\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
|
||||
ret = pci_priv->driver_ops->reinit(pci_priv->pci_dev,
|
||||
pci_priv->pci_device_id);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to reinit host driver, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
} else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) {
|
||||
ret = pci_priv->driver_ops->probe(pci_priv->pci_dev,
|
||||
pci_priv->pci_device_id);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to probe host driver, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
|
||||
set_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_pci_call_driver_remove(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
|
||||
if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Skip driver remove\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pci_priv->driver_ops) {
|
||||
cnss_pr_err("driver_ops is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
|
||||
pci_priv->driver_ops->shutdown(pci_priv->pci_dev);
|
||||
} else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
|
||||
pci_priv->driver_ops->remove(pci_priv->pci_dev);
|
||||
clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cnss_pci_call_driver_modem_status(struct cnss_pci_data *pci_priv,
|
||||
int modem_current_status)
|
||||
{
|
||||
struct cnss_wlan_driver *driver_ops;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (!driver_ops || !driver_ops->modem_status)
|
||||
return -EINVAL;
|
||||
|
||||
driver_ops->modem_status(pci_priv->pci_dev, modem_current_status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_qca6174_powerup(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
|
||||
ret = cnss_power_on_device(plat_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to power on device, err = %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = cnss_resume_pci_link(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
ret = cnss_pci_call_driver_probe(pci_priv);
|
||||
if (ret)
|
||||
goto suspend_link;
|
||||
|
||||
return 0;
|
||||
suspend_link:
|
||||
cnss_suspend_pci_link(pci_priv);
|
||||
power_off:
|
||||
cnss_power_off_device(plat_priv);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qca6174_shutdown(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
|
||||
cnss_pm_request_resume(pci_priv);
|
||||
|
||||
cnss_pci_call_driver_remove(pci_priv);
|
||||
|
||||
cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
|
||||
CNSS_BUS_WIDTH_NONE);
|
||||
cnss_pci_set_monitor_wake_intr(pci_priv, false);
|
||||
cnss_pci_set_auto_suspended(pci_priv, 0);
|
||||
|
||||
ret = cnss_suspend_pci_link(pci_priv);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
|
||||
|
||||
cnss_power_off_device(plat_priv);
|
||||
|
||||
clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_qca6174_crash_shutdown(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
if (pci_priv->driver_ops && pci_priv->driver_ops->crash_shutdown)
|
||||
pci_priv->driver_ops->crash_shutdown(pci_priv->pci_dev);
|
||||
}
|
||||
|
||||
static int cnss_qca6174_ramdump(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
struct cnss_ramdump_info *ramdump_info;
|
||||
struct ramdump_segment segment;
|
||||
|
||||
ramdump_info = &plat_priv->ramdump_info;
|
||||
if (!ramdump_info->ramdump_size)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&segment, 0, sizeof(segment));
|
||||
segment.v_address = ramdump_info->ramdump_va;
|
||||
segment.size = ramdump_info->ramdump_size;
|
||||
ret = do_ramdump(ramdump_info->ramdump_dev, &segment, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qca6290_powerup(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
unsigned int timeout;
|
||||
|
||||
if (plat_priv->ramdump_info_v2.dump_data_valid ||
|
||||
test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
|
||||
cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_DEINIT);
|
||||
cnss_pci_clear_dump_info(pci_priv);
|
||||
}
|
||||
|
||||
ret = cnss_power_on_device(plat_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to power on device, err = %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = cnss_resume_pci_link(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
timeout = cnss_get_qmi_timeout();
|
||||
|
||||
ret = cnss_pci_start_mhi(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to start MHI, err = %d\n", ret);
|
||||
if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state) &&
|
||||
!pci_priv->pci_link_down_ind && timeout)
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(timeout >> 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_bit(USE_CORE_ONLY_FW, cnss_get_debug_quirks())) {
|
||||
clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnss_set_pin_connect_status(plat_priv);
|
||||
|
||||
if (*cnss_get_qmi_bypass()) {
|
||||
ret = cnss_pci_call_driver_probe(pci_priv);
|
||||
if (ret)
|
||||
goto stop_mhi;
|
||||
} else if (timeout) {
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(timeout << 1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
stop_mhi:
|
||||
cnss_pci_stop_mhi(pci_priv);
|
||||
cnss_suspend_pci_link(pci_priv);
|
||||
power_off:
|
||||
cnss_power_off_device(plat_priv);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qca6290_shutdown(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
|
||||
cnss_pm_request_resume(pci_priv);
|
||||
|
||||
cnss_pci_call_driver_remove(pci_priv);
|
||||
|
||||
cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
|
||||
CNSS_BUS_WIDTH_NONE);
|
||||
cnss_pci_set_monitor_wake_intr(pci_priv, false);
|
||||
cnss_pci_set_auto_suspended(pci_priv, 0);
|
||||
|
||||
cnss_pci_stop_mhi(pci_priv);
|
||||
|
||||
ret = cnss_suspend_pci_link(pci_priv);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
|
||||
|
||||
cnss_power_off_device(plat_priv);
|
||||
|
||||
clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_qca6290_crash_shutdown(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
int ret = 0;
|
||||
|
||||
cnss_pr_dbg("Crash shutdown with driver_state 0x%lx\n",
|
||||
plat_priv->driver_state);
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Ignore crash shutdown\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RDDM_KERNEL_PANIC);
|
||||
if (ret) {
|
||||
cnss_pr_err("Fail to complete RDDM, err = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
cnss_pci_collect_dump_info(pci_priv);
|
||||
}
|
||||
|
||||
static int cnss_qca6290_ramdump(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
|
||||
struct cnss_dump_data *dump_data = &info_v2->dump_data;
|
||||
struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr;
|
||||
struct ramdump_segment *ramdump_segs, *s;
|
||||
int i, ret = 0;
|
||||
|
||||
if (!info_v2->dump_data_valid ||
|
||||
dump_data->nentries == 0)
|
||||
return 0;
|
||||
|
||||
ramdump_segs = kcalloc(dump_data->nentries,
|
||||
sizeof(*ramdump_segs),
|
||||
GFP_KERNEL);
|
||||
if (!ramdump_segs)
|
||||
return -ENOMEM;
|
||||
|
||||
s = ramdump_segs;
|
||||
for (i = 0; i < dump_data->nentries; i++) {
|
||||
s->address = dump_seg->address;
|
||||
s->v_address = dump_seg->v_address;
|
||||
s->size = dump_seg->size;
|
||||
s++;
|
||||
dump_seg++;
|
||||
}
|
||||
|
||||
ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs,
|
||||
dump_data->nentries);
|
||||
kfree(ramdump_segs);
|
||||
|
||||
cnss_pci_set_mhi_state(plat_priv->bus_priv, CNSS_MHI_DEINIT);
|
||||
cnss_pci_clear_dump_info(plat_priv->bus_priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_pci_dev_powerup(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (pci_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_qca6174_powerup(pci_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
ret = cnss_qca6290_powerup(pci_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%x\n",
|
||||
pci_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_pci_dev_shutdown(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (pci_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_qca6174_shutdown(pci_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
ret = cnss_qca6290_shutdown(pci_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%x\n",
|
||||
pci_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_pci_dev_crash_shutdown(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (pci_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
cnss_qca6174_crash_shutdown(pci_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
cnss_qca6290_crash_shutdown(pci_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%x\n",
|
||||
pci_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_pci_dev_ramdump(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (pci_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_qca6174_ramdump(pci_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
ret = cnss_qca6290_ramdump(pci_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id found: 0x%x\n",
|
||||
pci_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
|
||||
struct cnss_pci_data *pci_priv;
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pci_priv = plat_priv->bus_priv;
|
||||
if (!pci_priv) {
|
||||
cnss_pr_err("pci_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pci_priv->driver_ops) {
|
||||
cnss_pr_err("Driver has already registered\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
ret = cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_REGISTER_DRIVER,
|
||||
CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
|
||||
driver_ops);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_wlan_register_driver);
|
||||
|
||||
void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
|
||||
CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_wlan_unregister_driver);
|
||||
|
||||
int cnss_pci_register_driver_hdlr(struct cnss_pci_data *pci_priv,
|
||||
void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
|
||||
set_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
|
||||
pci_priv->driver_ops = data;
|
||||
|
||||
ret = cnss_pci_dev_powerup(pci_priv);
|
||||
if (ret) {
|
||||
clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
|
||||
pci_priv->driver_ops = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
|
||||
set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
|
||||
cnss_pci_dev_shutdown(pci_priv);
|
||||
pci_priv->driver_ops = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -387,7 +914,7 @@ static int cnss_pci_suspend(struct device *dev)
|
|||
if (!plat_priv)
|
||||
goto out;
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (driver_ops && driver_ops->suspend) {
|
||||
ret = driver_ops->suspend(pci_dev, state);
|
||||
if (ret) {
|
||||
|
@ -459,7 +986,7 @@ static int cnss_pci_resume(struct device *dev)
|
|||
cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
|
||||
}
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (driver_ops && driver_ops->resume) {
|
||||
ret = driver_ops->resume(pci_dev);
|
||||
if (ret)
|
||||
|
@ -488,7 +1015,7 @@ static int cnss_pci_suspend_noirq(struct device *dev)
|
|||
if (!plat_priv)
|
||||
goto out;
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (driver_ops && driver_ops->suspend_noirq)
|
||||
ret = driver_ops->suspend_noirq(pci_dev);
|
||||
|
||||
|
@ -511,7 +1038,7 @@ static int cnss_pci_resume_noirq(struct device *dev)
|
|||
if (!plat_priv)
|
||||
goto out;
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (driver_ops && driver_ops->resume_noirq &&
|
||||
!pci_priv->pci_link_down_ind)
|
||||
ret = driver_ops->resume_noirq(pci_dev);
|
||||
|
@ -542,7 +1069,7 @@ static int cnss_pci_runtime_suspend(struct device *dev)
|
|||
|
||||
cnss_pr_dbg("Runtime suspend start\n");
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (driver_ops && driver_ops->runtime_ops &&
|
||||
driver_ops->runtime_ops->runtime_suspend)
|
||||
ret = driver_ops->runtime_ops->runtime_suspend(pci_dev);
|
||||
|
@ -574,7 +1101,7 @@ static int cnss_pci_runtime_resume(struct device *dev)
|
|||
|
||||
cnss_pr_dbg("Runtime resume start\n");
|
||||
|
||||
driver_ops = plat_priv->driver_ops;
|
||||
driver_ops = pci_priv->driver_ops;
|
||||
if (driver_ops && driver_ops->runtime_ops &&
|
||||
driver_ops->runtime_ops->runtime_resume)
|
||||
ret = driver_ops->runtime_ops->runtime_resume(pci_dev);
|
||||
|
@ -1054,13 +1581,19 @@ void cnss_get_msi_address(struct device *dev, u32 *msi_addr_low,
|
|||
}
|
||||
EXPORT_SYMBOL(cnss_get_msi_address);
|
||||
|
||||
static char *get_wake_msi_name(void)
|
||||
{
|
||||
return (char *)WAKE_MSI_NAME;
|
||||
}
|
||||
|
||||
u32 cnss_pci_get_wake_msi(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
int ret, num_vectors;
|
||||
u32 user_base_data, base_vector;
|
||||
char *wake_msi_name = get_wake_msi_name();
|
||||
|
||||
ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
WAKE_MSI_NAME, &num_vectors,
|
||||
wake_msi_name, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
|
||||
if (ret) {
|
||||
|
@ -1286,8 +1819,8 @@ static void cnss_mhi_notify_status(enum MHI_CB_REASON reason, void *priv)
|
|||
|
||||
cnss_pr_dbg("MHI status cb is called with reason %d\n", reason);
|
||||
|
||||
if (plat_priv->driver_ops && plat_priv->driver_ops->update_status)
|
||||
plat_priv->driver_ops->update_status(pci_priv->pci_dev,
|
||||
if (pci_priv->driver_ops && pci_priv->driver_ops->update_status)
|
||||
pci_priv->driver_ops->update_status(pci_priv->pci_dev,
|
||||
CNSS_FW_DOWN);
|
||||
|
||||
set_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
|
||||
|
|
|
@ -62,6 +62,7 @@ struct cnss_pci_data {
|
|||
const struct pci_device_id *pci_device_id;
|
||||
u32 device_id;
|
||||
u16 revision_id;
|
||||
struct cnss_wlan_driver *driver_ops;
|
||||
bool pci_link_state;
|
||||
bool pci_link_down_ind;
|
||||
struct pci_saved_state *saved_state;
|
||||
|
@ -155,5 +156,15 @@ 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);
|
||||
|
||||
int cnss_pci_call_driver_probe(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_call_driver_remove(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_dev_powerup(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_dev_shutdown(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_dev_crash_shutdown(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_dev_ramdump(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_register_driver_hdlr(struct cnss_pci_data *pci_priv, void *data);
|
||||
int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_call_driver_modem_status(struct cnss_pci_data *pci_priv,
|
||||
int modem_current_status);
|
||||
int cnss_pci_recovery_update_status(struct cnss_pci_data *pci_priv);
|
||||
#endif /* _CNSS_PCI_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue