mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
Merge "cnss2: Add support to remove WLAN recovery from SSR framework"
This commit is contained in:
commit
8cc45cd760
6 changed files with 174 additions and 30 deletions
|
|
@ -250,6 +250,21 @@ void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv, bool in_panic)
|
|||
}
|
||||
}
|
||||
|
||||
void cnss_bus_device_crashed(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_device_crashed(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_call_driver_probe(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ int cnss_bus_qmi_send_put(struct cnss_plat_data *plat_priv);
|
|||
void cnss_bus_fw_boot_timeout_hdlr(struct timer_list *t);
|
||||
void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv,
|
||||
bool in_panic);
|
||||
void cnss_bus_device_crashed(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);
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <linux/timer.h>
|
||||
#include <soc/qcom/minidump.h>
|
||||
#include <soc/qcom/ramdump.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "bus.h"
|
||||
|
|
@ -26,7 +24,7 @@
|
|||
#define CNSS_DUMP_NAME "CNSS_WLAN"
|
||||
#define CNSS_DUMP_DESC_SIZE 0x1000
|
||||
#define CNSS_DUMP_SEG_VER 0x1
|
||||
#define WLAN_RECOVERY_DELAY 1000
|
||||
#define RECOVERY_DELAY_MS 100
|
||||
#define FILE_SYSTEM_READY 1
|
||||
#define FW_READY_TIMEOUT 20000
|
||||
#define FW_ASSERT_TIMEOUT 5000
|
||||
|
|
@ -785,7 +783,7 @@ static void cnss_put_resources(struct cnss_plat_data *plat_priv)
|
|||
cnss_put_vreg_type(plat_priv, CNSS_VREG_PRIM);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESOC
|
||||
#if IS_ENABLED(CONFIG_ESOC) && IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
|
||||
static int cnss_modem_notifier_nb(struct notifier_block *nb,
|
||||
unsigned long code,
|
||||
void *ss_handle)
|
||||
|
|
@ -893,6 +891,7 @@ static inline int cnss_register_esoc(struct cnss_plat_data *plat_priv)
|
|||
static inline void cnss_unregister_esoc(struct cnss_plat_data *plat_priv) {}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
|
||||
static int cnss_subsys_powerup(const struct subsys_desc *subsys_desc)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
|
@ -985,6 +984,36 @@ static int cnss_subsys_ramdump(int enable,
|
|||
return cnss_bus_dev_ramdump(plat_priv);
|
||||
}
|
||||
|
||||
static void cnss_recovery_work_handler(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static void cnss_recovery_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv =
|
||||
container_of(work, struct cnss_plat_data, recovery_work);
|
||||
|
||||
if (!plat_priv->recovery_enabled)
|
||||
panic("subsys-restart: Resetting the SoC wlan crashed\n");
|
||||
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
msleep(RECOVERY_DELAY_MS);
|
||||
cnss_bus_dev_powerup(plat_priv);
|
||||
}
|
||||
|
||||
void cnss_device_crashed(struct device *dev)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
schedule_work(&plat_priv->recovery_work);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_device_crashed);
|
||||
#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
|
||||
|
||||
void *cnss_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
|
|
@ -1019,9 +1048,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_subsys_info *subsys_info =
|
||||
&plat_priv->subsys_info;
|
||||
|
||||
plat_priv->recovery_count++;
|
||||
|
||||
if (plat_priv->device_id == QCA6174_DEVICE_ID)
|
||||
|
|
@ -1054,11 +1080,7 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!subsys_info->subsys_device)
|
||||
return 0;
|
||||
|
||||
subsys_set_crash_status(subsys_info->subsys_device, true);
|
||||
subsystem_restart_dev(subsys_info->subsys_device);
|
||||
cnss_bus_device_crashed(plat_priv);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -1629,6 +1651,7 @@ int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
|
||||
int cnss_register_subsys(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -1680,6 +1703,70 @@ void cnss_unregister_subsys(struct cnss_plat_data *plat_priv)
|
|||
subsys_unregister(subsys_info->subsys_device);
|
||||
}
|
||||
|
||||
static void *cnss_create_ramdump_device(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_subsys_info *subsys_info = &plat_priv->subsys_info;
|
||||
|
||||
return create_ramdump_device(subsys_info->subsys_desc.name,
|
||||
subsys_info->subsys_desc.dev);
|
||||
}
|
||||
|
||||
static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv,
|
||||
void *ramdump_dev)
|
||||
{
|
||||
destroy_ramdump_device(ramdump_dev);
|
||||
}
|
||||
#else
|
||||
static int cnss_panic_handler(struct notifier_block *nb, unsigned long action,
|
||||
void *data)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv =
|
||||
container_of(nb, struct cnss_plat_data, panic_nb);
|
||||
|
||||
cnss_bus_dev_crash_shutdown(plat_priv);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
int cnss_register_subsys(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
plat_priv->panic_nb.notifier_call = cnss_panic_handler;
|
||||
ret = atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&plat_priv->panic_nb);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to register panic handler\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cnss_unregister_subsys(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&plat_priv->panic_nb);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to unregister panic handler\n");
|
||||
}
|
||||
|
||||
static void *cnss_create_ramdump_device(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return &plat_priv->plat_dev->dev;
|
||||
}
|
||||
|
||||
static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv,
|
||||
void *ramdump_dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
|
||||
|
||||
static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_ramdump_info *ramdump_info;
|
||||
|
|
@ -1703,12 +1790,10 @@ static int cnss_register_ramdump_v1(struct cnss_plat_data *plat_priv)
|
|||
{
|
||||
int ret = 0;
|
||||
struct device *dev;
|
||||
struct cnss_subsys_info *subsys_info;
|
||||
struct cnss_ramdump_info *ramdump_info;
|
||||
u32 ramdump_size = 0;
|
||||
|
||||
dev = &plat_priv->plat_dev->dev;
|
||||
subsys_info = &plat_priv->subsys_info;
|
||||
ramdump_info = &plat_priv->ramdump_info;
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
|
||||
|
|
@ -1736,9 +1821,7 @@ static int cnss_register_ramdump_v1(struct cnss_plat_data *plat_priv)
|
|||
goto free_ramdump;
|
||||
}
|
||||
|
||||
ramdump_info->ramdump_dev =
|
||||
create_ramdump_device(subsys_info->subsys_desc.name,
|
||||
subsys_info->subsys_desc.dev);
|
||||
ramdump_info->ramdump_dev = cnss_create_ramdump_device(plat_priv);
|
||||
if (!ramdump_info->ramdump_dev) {
|
||||
cnss_pr_err("Failed to create ramdump device!");
|
||||
ret = -ENOMEM;
|
||||
|
|
@ -1762,7 +1845,8 @@ static void cnss_unregister_ramdump_v1(struct cnss_plat_data *plat_priv)
|
|||
ramdump_info = &plat_priv->ramdump_info;
|
||||
|
||||
if (ramdump_info->ramdump_dev)
|
||||
destroy_ramdump_device(ramdump_info->ramdump_dev);
|
||||
cnss_destroy_ramdump_device(plat_priv,
|
||||
ramdump_info->ramdump_dev);
|
||||
|
||||
if (ramdump_info->ramdump_va)
|
||||
dma_free_coherent(dev, ramdump_info->ramdump_size,
|
||||
|
|
@ -1794,14 +1878,12 @@ static int cnss_ignore_dump_data_reg_fail(int ret)
|
|||
static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_subsys_info *subsys_info;
|
||||
struct cnss_ramdump_info_v2 *info_v2;
|
||||
struct cnss_dump_data *dump_data;
|
||||
struct msm_dump_entry dump_entry;
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
u32 ramdump_size = 0;
|
||||
|
||||
subsys_info = &plat_priv->subsys_info;
|
||||
info_v2 = &plat_priv->ramdump_info_v2;
|
||||
dump_data = &info_v2->dump_data;
|
||||
|
||||
|
|
@ -1833,9 +1915,7 @@ static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv)
|
|||
goto free_ramdump;
|
||||
}
|
||||
|
||||
info_v2->ramdump_dev =
|
||||
create_ramdump_device(subsys_info->subsys_desc.name,
|
||||
subsys_info->subsys_desc.dev);
|
||||
info_v2->ramdump_dev = cnss_create_ramdump_device(plat_priv);
|
||||
if (!info_v2->ramdump_dev) {
|
||||
cnss_pr_err("Failed to create ramdump device!\n");
|
||||
ret = -ENOMEM;
|
||||
|
|
@ -1857,7 +1937,7 @@ static void cnss_unregister_ramdump_v2(struct cnss_plat_data *plat_priv)
|
|||
info_v2 = &plat_priv->ramdump_info_v2;
|
||||
|
||||
if (info_v2->ramdump_dev)
|
||||
destroy_ramdump_device(info_v2->ramdump_dev);
|
||||
cnss_destroy_ramdump_device(plat_priv, info_v2->ramdump_dev);
|
||||
|
||||
kfree(info_v2->dump_data_vaddr);
|
||||
info_v2->dump_data_vaddr = NULL;
|
||||
|
|
@ -2051,6 +2131,32 @@ static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv)
|
|||
kfree(bus_bw_info->cfg_table);
|
||||
}
|
||||
|
||||
static ssize_t recovery_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
|
||||
unsigned int recovery = 0;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (sscanf(buf, "%du", &recovery) != 1) {
|
||||
cnss_pr_err("Invalid recovery sysfs command\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (recovery)
|
||||
plat_priv->recovery_enabled = true;
|
||||
else
|
||||
plat_priv->recovery_enabled = false;
|
||||
|
||||
cnss_pr_dbg("%s WLAN recovery, count is %zu\n",
|
||||
plat_priv->recovery_enabled ? "Enable" : "Disable", count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t shutdown_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
|
|
@ -2114,10 +2220,12 @@ static ssize_t fs_ready_store(struct device *dev,
|
|||
|
||||
static DEVICE_ATTR_WO(fs_ready);
|
||||
static DEVICE_ATTR_WO(shutdown);
|
||||
static DEVICE_ATTR_WO(recovery);
|
||||
|
||||
static struct attribute *cnss_attrs[] = {
|
||||
&dev_attr_fs_ready.attr,
|
||||
&dev_attr_shutdown.attr,
|
||||
&dev_attr_recovery.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -2243,6 +2351,7 @@ static int cnss_misc_init(struct cnss_plat_data *plat_priv)
|
|||
cnss_pr_err("Failed to init platform device wakeup source, err = %d\n",
|
||||
ret);
|
||||
|
||||
INIT_WORK(&plat_priv->recovery_work, cnss_recovery_work_handler);
|
||||
init_completion(&plat_priv->power_up_complete);
|
||||
init_completion(&plat_priv->cal_complete);
|
||||
init_completion(&plat_priv->rddm_complete);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#define _CNSS_MAIN_H
|
||||
|
||||
#include <asm/arch_timer.h>
|
||||
#ifdef CONFIG_ESOC
|
||||
#if IS_ENABLED(CONFIG_ESOC)
|
||||
#include <linux/esoc_client.h>
|
||||
#endif
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
@ -14,7 +14,11 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <net/cnss2.h>
|
||||
#include <soc/qcom/memory_dump.h>
|
||||
#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
|
||||
#include <soc/qcom/ramdump.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include <soc/qcom/subsystem_restart.h>
|
||||
#endif
|
||||
|
||||
#include "qmi.h"
|
||||
|
||||
|
|
@ -83,14 +87,16 @@ struct cnss_pinctrl_info {
|
|||
struct pinctrl_state *wlan_en_sleep;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
|
||||
struct cnss_subsys_info {
|
||||
struct subsys_device *subsys_device;
|
||||
struct subsys_desc subsys_desc;
|
||||
void *subsys_handle;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct cnss_ramdump_info {
|
||||
struct ramdump_device *ramdump_dev;
|
||||
void *ramdump_dev;
|
||||
unsigned long ramdump_size;
|
||||
void *ramdump_va;
|
||||
phys_addr_t ramdump_pa;
|
||||
|
|
@ -114,14 +120,14 @@ struct cnss_dump_data {
|
|||
};
|
||||
|
||||
struct cnss_ramdump_info_v2 {
|
||||
struct ramdump_device *ramdump_dev;
|
||||
void *ramdump_dev;
|
||||
unsigned long ramdump_size;
|
||||
void *dump_data_vaddr;
|
||||
u8 dump_data_valid;
|
||||
struct cnss_dump_data dump_data;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ESOC
|
||||
#if IS_ENABLED(CONFIG_ESOC)
|
||||
struct cnss_esoc_info {
|
||||
struct esoc_desc *esoc_desc;
|
||||
u8 notify_modem_status;
|
||||
|
|
@ -342,26 +348,31 @@ struct cnss_plat_data {
|
|||
struct list_head vreg_list;
|
||||
struct list_head clk_list;
|
||||
struct cnss_pinctrl_info pinctrl_info;
|
||||
#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
|
||||
struct cnss_subsys_info subsys_info;
|
||||
#endif
|
||||
struct cnss_ramdump_info ramdump_info;
|
||||
struct cnss_ramdump_info_v2 ramdump_info_v2;
|
||||
#ifdef CONFIG_ESOC
|
||||
#if IS_ENABLED(CONFIG_ESOC)
|
||||
struct cnss_esoc_info esoc_info;
|
||||
#endif
|
||||
struct cnss_bus_bw_info bus_bw_info;
|
||||
struct notifier_block modem_nb;
|
||||
struct notifier_block reboot_nb;
|
||||
struct notifier_block panic_nb;
|
||||
struct cnss_platform_cap cap;
|
||||
struct pm_qos_request qos_request;
|
||||
struct cnss_device_version device_version;
|
||||
unsigned long device_id;
|
||||
enum cnss_driver_status driver_status;
|
||||
u32 recovery_count;
|
||||
u8 recovery_enabled;
|
||||
unsigned long driver_state;
|
||||
struct list_head event_list;
|
||||
spinlock_t event_lock; /* spinlock for driver work event handling */
|
||||
struct work_struct event_work;
|
||||
struct workqueue_struct *event_wq;
|
||||
struct work_struct recovery_work;
|
||||
struct qmi_handle qmi_wlfw;
|
||||
struct wlfw_rf_chip_info chip_info;
|
||||
struct wlfw_rf_board_info board_info;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/completion.h>
|
||||
#include <soc/qcom/ramdump.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "bus.h"
|
||||
|
|
@ -4203,6 +4202,14 @@ void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv)
|
|||
plat_priv->ramdump_info_v2.dump_data_valid = false;
|
||||
}
|
||||
|
||||
void cnss_pci_device_crashed(struct cnss_pci_data *pci_priv)
|
||||
{
|
||||
if (!pci_priv)
|
||||
return;
|
||||
|
||||
cnss_device_crashed(&pci_priv->pci_dev->dev);
|
||||
}
|
||||
|
||||
static int cnss_mhi_pm_runtime_get(struct mhi_controller *mhi_ctrl, void *priv)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = priv;
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ void cnss_pci_free_qdss_mem(struct cnss_pci_data *pci_priv);
|
|||
int cnss_pci_load_m3(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_start_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_device_crashed(struct cnss_pci_data *pci_priv);
|
||||
void cnss_pci_clear_dump_info(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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue