diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2019-09-23 00:43:38 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-09-23 00:43:38 -0700 |
| commit | c7e9684caf25f542179461d58d4de127cd809d1c (patch) | |
| tree | b3a681131a2a9eb8b783df45035fb75e5e87f770 | |
| parent | 16ede3da1a2f9ce05c3980905b2de1484cbea170 (diff) | |
| parent | 63058361746dfffebabded6c741665059985dcd0 (diff) | |
Merge "cnss2: support wakeup using gpio"
| -rw-r--r-- | drivers/net/wireless/cnss2/main.c | 34 | ||||
| -rw-r--r-- | drivers/net/wireless/cnss2/main.h | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/cnss2/power.c | 52 |
3 files changed, 88 insertions, 1 deletions
diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 498650e08d2a..baa469ad2f6a 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -61,6 +61,40 @@ module_param(quirks, ulong, 0600); MODULE_PARM_DESC(quirks, "Debug quirks for the driver"); #endif +static unsigned int wow_wake_gpionum; +#ifdef CONFIG_CNSS2_DEBUG +module_param(wow_wake_gpionum, uint, 0600); +MODULE_PARM_DESC(wow_wake_gpionum, "configure gpio number for wow wake"); +#endif + +static unsigned int wow_wake_enable; +int cnss_enable_wow_wake(const char *val, const struct kernel_param *kp) +{ + int ret; + unsigned int prev_val; + + prev_val = *(unsigned int *)kp->arg; + ret = param_set_uint(val, kp); + if (ret || prev_val == wow_wake_enable) { + cnss_pr_err("failed set new wow_enable ret = %d", ret); + return ret; + } + if (wow_wake_enable) { + if (!wow_wake_gpionum) + wow_wake_gpionum = HOST_WAKE_GPIO_IN; + cnss_set_wlan_chip_to_host_wakeup(wow_wake_gpionum); + } + return 0; +} + +static const struct kernel_param_ops cnss_param_ops_uint = { + .set = &cnss_enable_wow_wake, + .get = ¶m_get_uint +}; + +module_param_cb(wow_wake_enable, &cnss_param_ops_uint, + &wow_wake_enable, 0600); + static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = { "qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin", "utfbd30.bin", "epping30.bin", "evicted30.bin" diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index 1b7c67b90795..524a1fa0dcf4 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -31,6 +31,7 @@ #define CNSS_EVENT_SYNC_UNINTERRUPTIBLE (CNSS_EVENT_SYNC | \ CNSS_EVENT_UNINTERRUPTIBLE) #define QCN7605_CALDB_SIZE 614400 +#define HOST_WAKE_GPIO_IN 144 enum cnss_dev_bus_type { CNSS_BUS_NONE = -1, @@ -259,4 +260,6 @@ 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); bool is_qcn7605_device(u16 device_id); +void cnss_set_wlan_chip_to_host_wakeup(unsigned int wakeup_gpio_num); +int cnss_enable_wow_wake(const char *val, const struct kernel_param *kp); #endif /* _CNSS_MAIN_H */ diff --git a/drivers/net/wireless/cnss2/power.c b/drivers/net/wireless/cnss2/power.c index 8a58a5357765..ed145d7049be 100644 --- a/drivers/net/wireless/cnss2/power.c +++ b/drivers/net/wireless/cnss2/power.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ #include <linux/of.h> #include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> +#include <linux/gpio.h> #include "main.h" #include "debug.h" @@ -388,3 +389,52 @@ void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv) plat_priv->pin_result.host_pin_result = pin_status; } + +static irqreturn_t wlan_wakeup_interrupt(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +void cnss_set_wlan_chip_to_host_wakeup(unsigned int wakeup_gpio_num) +{ + int ret = 0; + int wakeup_irq_num; + + ret = gpio_request(wakeup_gpio_num, "qcom_wlan_wakeup"); + if (ret) + cnss_pr_err("wakeup gpio request failed\n"); + + ret = gpio_direction_input(wakeup_gpio_num); + if (ret) { + cnss_pr_err("wake gpio set dir output failed\n"); + goto free_gpio; + } + + wakeup_irq_num = gpio_to_irq(wakeup_gpio_num); + if (wakeup_irq_num < 0) { + cnss_pr_err("wake gpio_to_irq err %d\n", wakeup_irq_num); + goto free_gpio; + } + ret = request_irq(wakeup_irq_num, wlan_wakeup_interrupt, + IRQF_TRIGGER_FALLING, "qcom_wlan_wakeup_irq", NULL); + if (ret) { + cnss_pr_err("request_irq err %d\n", ret); + goto free_gpio; + } + + ret = enable_irq_wake(wakeup_irq_num); + if (!ret) { + cnss_pr_err("enable irq wakeup success %d\n", ret); + } else { + cnss_pr_err("enable irq wakeup FAILURE %d\n", ret); + goto irq_free; + } + ret = gpio_get_value(wakeup_gpio_num); + cnss_pr_err("gpio get val ret = %d wakeup_gpio_num %d\n", ret, + wakeup_gpio_num); + return; +irq_free: + free_irq(wakeup_irq_num, NULL); +free_gpio: + gpio_free(wakeup_gpio_num); +} |
