|
@@ -1,7 +1,7 @@
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
/*
|
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
|
|
|
|
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
*/
|
|
|
|
|
|
#include <linux/delay.h>
|
|
#include <linux/delay.h>
|
|
@@ -62,6 +62,7 @@
|
|
#define FW_ASSERT_TIMEOUT 5000
|
|
#define FW_ASSERT_TIMEOUT 5000
|
|
#define CNSS_EVENT_PENDING 2989
|
|
#define CNSS_EVENT_PENDING 2989
|
|
#define POWER_RESET_MIN_DELAY_MS 100
|
|
#define POWER_RESET_MIN_DELAY_MS 100
|
|
|
|
+#define MAX_NAME_LEN 12
|
|
|
|
|
|
#define CNSS_QUIRKS_DEFAULT 0
|
|
#define CNSS_QUIRKS_DEFAULT 0
|
|
#ifdef CONFIG_CNSS_EMULATION
|
|
#ifdef CONFIG_CNSS_EMULATION
|
|
@@ -1694,7 +1695,6 @@ int cnss_enable_dev_sol_irq(struct cnss_plat_data *plat_priv)
|
|
if (sol_gpio->dev_sol_gpio < 0 || sol_gpio->dev_sol_irq <= 0)
|
|
if (sol_gpio->dev_sol_gpio < 0 || sol_gpio->dev_sol_irq <= 0)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
- enable_irq(sol_gpio->dev_sol_irq);
|
|
|
|
ret = enable_irq_wake(sol_gpio->dev_sol_irq);
|
|
ret = enable_irq_wake(sol_gpio->dev_sol_irq);
|
|
if (ret)
|
|
if (ret)
|
|
cnss_pr_err("Failed to enable device SOL as wake IRQ, err = %d\n",
|
|
cnss_pr_err("Failed to enable device SOL as wake IRQ, err = %d\n",
|
|
@@ -1715,7 +1715,6 @@ int cnss_disable_dev_sol_irq(struct cnss_plat_data *plat_priv)
|
|
if (ret)
|
|
if (ret)
|
|
cnss_pr_err("Failed to disable device SOL as wake IRQ, err = %d\n",
|
|
cnss_pr_err("Failed to disable device SOL as wake IRQ, err = %d\n",
|
|
ret);
|
|
ret);
|
|
- disable_irq(sol_gpio->dev_sol_irq);
|
|
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -1735,9 +1734,15 @@ static irqreturn_t cnss_dev_sol_handler(int irq, void *data)
|
|
struct cnss_plat_data *plat_priv = data;
|
|
struct cnss_plat_data *plat_priv = data;
|
|
struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
|
|
struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
|
|
|
|
|
|
|
|
+ if (test_bit(CNSS_POWER_OFF, &plat_priv->driver_state)) {
|
|
|
|
+ cnss_pr_dbg("Ignore Dev SOL during device power off");
|
|
|
|
+ return IRQ_HANDLED;
|
|
|
|
+ }
|
|
|
|
+
|
|
sol_gpio->dev_sol_counter++;
|
|
sol_gpio->dev_sol_counter++;
|
|
- cnss_pr_dbg("WLAN device SOL IRQ (%u) is asserted #%u\n",
|
|
|
|
- irq, sol_gpio->dev_sol_counter);
|
|
|
|
|
|
+ cnss_pr_dbg("WLAN device SOL IRQ (%u) is asserted #%u, dev_sol_val: %d\n",
|
|
|
|
+ irq, sol_gpio->dev_sol_counter,
|
|
|
|
+ cnss_get_dev_sol_value(plat_priv));
|
|
|
|
|
|
/* Make sure abort current suspend */
|
|
/* Make sure abort current suspend */
|
|
cnss_pm_stay_awake(plat_priv);
|
|
cnss_pm_stay_awake(plat_priv);
|
|
@@ -3771,7 +3776,6 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
|
|
}
|
|
}
|
|
#endif /* CONFIG_QCOM_MEMORY_DUMP_V2 */
|
|
#endif /* CONFIG_QCOM_MEMORY_DUMP_V2 */
|
|
|
|
|
|
-#if IS_ENABLED(CONFIG_QCOM_MINIDUMP)
|
|
|
|
int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
|
|
int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
|
|
phys_addr_t *pa, unsigned long attrs)
|
|
phys_addr_t *pa, unsigned long attrs)
|
|
{
|
|
{
|
|
@@ -3791,6 +3795,7 @@ int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if IS_ENABLED(CONFIG_QCOM_MINIDUMP)
|
|
int cnss_minidump_add_region(struct cnss_plat_data *plat_priv,
|
|
int cnss_minidump_add_region(struct cnss_plat_data *plat_priv,
|
|
enum cnss_fw_dump_type type, int seg_no,
|
|
enum cnss_fw_dump_type type, int seg_no,
|
|
void *va, phys_addr_t pa, size_t size)
|
|
void *va, phys_addr_t pa, size_t size)
|
|
@@ -3872,16 +3877,29 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
#else
|
|
#else
|
|
-int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
|
|
|
|
- phys_addr_t *pa, unsigned long attrs)
|
|
|
|
-{
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
int cnss_minidump_add_region(struct cnss_plat_data *plat_priv,
|
|
int cnss_minidump_add_region(struct cnss_plat_data *plat_priv,
|
|
enum cnss_fw_dump_type type, int seg_no,
|
|
enum cnss_fw_dump_type type, int seg_no,
|
|
void *va, phys_addr_t pa, size_t size)
|
|
void *va, phys_addr_t pa, size_t size)
|
|
{
|
|
{
|
|
|
|
+ char name[MAX_NAME_LEN];
|
|
|
|
+
|
|
|
|
+ switch (type) {
|
|
|
|
+ case CNSS_FW_IMAGE:
|
|
|
|
+ snprintf(name, MAX_NAME_LEN, "FBC_%X", seg_no);
|
|
|
|
+ break;
|
|
|
|
+ case CNSS_FW_RDDM:
|
|
|
|
+ snprintf(name, MAX_NAME_LEN, "RDDM_%X", seg_no);
|
|
|
|
+ break;
|
|
|
|
+ case CNSS_FW_REMOTE_HEAP:
|
|
|
|
+ snprintf(name, MAX_NAME_LEN, "RHEAP_%X", seg_no);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ cnss_pr_err("Unknown dump type ID: %d\n", type);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cnss_pr_dbg("Dump region: %s, va: %pK, pa: %pa, size: 0x%zx\n",
|
|
|
|
+ name, va, &pa, size);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|