* [PATCH v3 0/2] ath6kl_sdio: add control of CHIP_PWD_L via GPIO
@ 2015-11-23 0:15 Steve deRosier
2015-11-23 0:15 ` [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin Steve deRosier
2015-11-23 0:15 ` [PATCH v3 2/2] ath6kl_sdio: Add power gpio reset feature into sdio driver for suspend Steve deRosier
0 siblings, 2 replies; 5+ messages in thread
From: Steve deRosier @ 2015-11-23 0:15 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath6kl, linux-wireless, Julian Calaby, Steve deRosier
This set of two patches adds the ablity for ath6kl_sdio to control the
CHIP_PWD_L pin on startup and for suspend/wakeup. This is importaint because
on some platforms, this is the only way to achieve minimum power consumption.
The CHIP_PWD_L pin is used to hold the ath chip in reset and this is the
proper way to achieve its lowest power state (per QCA's datasheets).
This GPIO is controled by the kernel standard GPIOLIB and as such depends on
CONFIG_GPIOLIB. If this isn't enabled, then the various usages will generally
compile out. Even if enabled, by default the GPIO is set to an invalid number,
and each use will check: if not a valid GPIO, then behavior will be unchanged.
This adds a new module parameter to allow the user to set the GPIO to use.
To utilize:
modprobe ath6kl_sdio reset_pwd_gpio=28
Where "28" should be replaced by the GPIO id of the pin connected to the
CHIP_PWD_L pin on the wifi chip.
v3: Minor changes due to review comments
* Move constant to top of file
* Remove unnecessary gpio valid check
v2: Changes due to review comments
* Fix __init and __exit on gpio init/cleanup functions
* Remove unnecessary #ifdef defines on GPIO as gpio.h already takes care of it
* Utilize already available ARCH_NR_GPIOS
* Remove msleep on exit as the problem it resolves is taken care of a different
patch.
This applies against kvalo/ath.git master branch
Steve deRosier (2):
ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin
ath6kl_sdio: Add power gpio reset feature into sdio driver for suspend
drivers/net/wireless/ath/ath6kl/sdio.c | 113 ++++++++++++++++++++++++++++++++-
1 file changed, 110 insertions(+), 3 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin
2015-11-23 0:15 [PATCH v3 0/2] ath6kl_sdio: add control of CHIP_PWD_L via GPIO Steve deRosier
@ 2015-11-23 0:15 ` Steve deRosier
2015-12-01 13:01 ` Kalle Valo
2015-12-06 0:19 ` kbuild test robot
2015-11-23 0:15 ` [PATCH v3 2/2] ath6kl_sdio: Add power gpio reset feature into sdio driver for suspend Steve deRosier
1 sibling, 2 replies; 5+ messages in thread
From: Steve deRosier @ 2015-11-23 0:15 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath6kl, linux-wireless, Julian Calaby, Steve deRosier
Many ath6k chips have a reset pin, usually labeled CHIP_PWD_L. This pin can
be pulled low by the host processor to hold the wifi chip in reset. By
holding the chip in reset, the lowest power consumption available can be
achieved.
This adds a module parameter so the ath6kl_sdio driver can control the
CHIP_PWD_L pin if the implementer so desires. This code is only available
if GPIOLIB is configured.
Signed-off-by: Steve deRosier <steve.derosier@lairdtech.com>
---
drivers/net/wireless/ath/ath6kl/sdio.c | 70 +++++++++++++++++++++++++++++++++-
1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index eab0ab9..d06aa41 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -23,6 +23,7 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sd.h>
+#include <linux/gpio.h>
#include "hif.h"
#include "hif-ops.h"
#include "target.h"
@@ -69,6 +70,20 @@ struct ath6kl_sdio {
spinlock_t wr_async_lock;
};
+/* Delay to avoid the mmc driver calling the probe on the prior notice of
+ * the chip, which we just killed. If this is missing, it results in a
+ * spurious warning:
+ * "ath6kl_sdio: probe of mmc0:0001:1 failed with error -110"
+ *
+ * Time chosen experimentally, with padding
+ */
+#define ATH6KL_MMC_PROBE_DELAY 150
+static unsigned int reset_pwd_gpio = ARCH_NR_GPIOS;
+#ifdef CONFIG_GPIOLIB
+module_param(reset_pwd_gpio, uint, 0644);
+MODULE_PARM_DESC(reset_pwd_gpio, "WIFI CHIP_PWD reset pin GPIO");
+#endif
+
#define CMD53_ARG_READ 0
#define CMD53_ARG_WRITE 1
#define CMD53_ARG_BLOCK_BASIS 1
@@ -1414,20 +1429,73 @@ static struct sdio_driver ath6kl_sdio_driver = {
.drv.pm = ATH6KL_SDIO_PM_OPS,
};
+static int ath6kl_sdio_init_gpio(void)
+{
+ int ret = 0;
+
+ if (gpio_is_valid(reset_pwd_gpio)) {
+ /* Request the reset GPIO, and assert it to make sure we get a
+ * clean boot in-case we had a floating input or other issue.
+ */
+ ret = gpio_request_one(reset_pwd_gpio,
+ GPIOF_OUT_INIT_LOW |
+ GPIOF_EXPORT_DIR_FIXED,
+ "WIFI_RESET");
+ if (ret) {
+ ath6kl_err("Unable to get WIFI power gpio: %d\n", ret);
+ return ret;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_SUSPEND, "Setup wifi gpio #%d\n",
+ reset_pwd_gpio);
+ usleep_range(20, 50); /* Pin must be asserted at least 5 usec */
+ gpio_set_value(reset_pwd_gpio, 1); /* De-assert the pin */
+
+ msleep(ATH6KL_MMC_PROBE_DELAY);
+ }
+
+ return 0;
+}
+
+static void ath6kl_sdio_release_gpio(void)
+{
+ if (gpio_is_valid(reset_pwd_gpio)) {
+ /* Be sure we leave the chip in reset when we unload and also
+ * release the GPIO
+ */
+ gpio_set_value(reset_pwd_gpio, 0);
+ gpio_free(reset_pwd_gpio);
+ }
+}
+
static int __init ath6kl_sdio_init(void)
{
int ret;
- ret = sdio_register_driver(&ath6kl_sdio_driver);
+ ret = ath6kl_sdio_init_gpio();
if (ret)
+ goto err_gpio;
+
+ ret = sdio_register_driver(&ath6kl_sdio_driver);
+ if (ret) {
ath6kl_err("sdio driver registration failed: %d\n", ret);
+ goto err_register;
+ }
return ret;
+
+err_register:
+ ath6kl_sdio_release_gpio();
+
+err_gpio:
+ return ret;
}
static void __exit ath6kl_sdio_exit(void)
{
sdio_unregister_driver(&ath6kl_sdio_driver);
+
+ ath6kl_sdio_release_gpio();
}
module_init(ath6kl_sdio_init);
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] ath6kl_sdio: Add power gpio reset feature into sdio driver for suspend
2015-11-23 0:15 [PATCH v3 0/2] ath6kl_sdio: add control of CHIP_PWD_L via GPIO Steve deRosier
2015-11-23 0:15 ` [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin Steve deRosier
@ 2015-11-23 0:15 ` Steve deRosier
1 sibling, 0 replies; 5+ messages in thread
From: Steve deRosier @ 2015-11-23 0:15 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath6kl, linux-wireless, Julian Calaby, Steve deRosier
This change adds pm suspend callbacks in order to trigger a gpio line
to push the CHIP_PWD_L reset/power line low on suspend. This puts the chip
into the lowest power state on suspend. On resume, it releases the line,
allowing the chip to boot. Slower, but provides a clean reset of the
chip and recovery from standby.
Signed-off-by: Steve deRosier <steve.derosier@lairdtech.com>
---
drivers/net/wireless/ath/ath6kl/sdio.c | 40 ++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index d06aa41..cef311d 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -1295,8 +1295,44 @@ static int ath6kl_sdio_pm_resume(struct device *device)
return 0;
}
-static SIMPLE_DEV_PM_OPS(ath6kl_sdio_pm_ops, ath6kl_sdio_pm_suspend,
- ath6kl_sdio_pm_resume);
+/* Below handlers leverage the PM system to make sure we turn on and off
+ * the power gpio at the right time. If we do it in the earlier power on
+ * and off handlers for the sdio, we get errors from the mmc subsystem.
+ */
+static int ath6kl_sdio_pm_suspend_late(struct device *device)
+{
+ ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm ath6kl_sdio_pm_suspend_late\n");
+
+ if (gpio_is_valid(reset_pwd_gpio))
+ gpio_set_value(reset_pwd_gpio, 0);
+
+ return 0;
+}
+
+static int ath6kl_sdio_pm_resume_early(struct device *device)
+{
+ ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm ath6kl_sdio_pm_resume_early\n");
+
+ if (gpio_is_valid(reset_pwd_gpio)) {
+ gpio_set_value(reset_pwd_gpio, 1);
+ usleep_range(1000, 5000); /* wait for power up */
+ }
+ return 0;
+}
+
+/* The GPIO version requires the more complex dev_pm_ops setup */
+const struct dev_pm_ops ath6kl_sdio_pm_ops = {
+ .suspend = ath6kl_sdio_pm_suspend,
+ .suspend_late = ath6kl_sdio_pm_suspend_late,
+ .resume_early = ath6kl_sdio_pm_resume_early,
+ .resume = ath6kl_sdio_pm_resume,
+ .freeze = ath6kl_sdio_pm_suspend,
+ .thaw = ath6kl_sdio_pm_resume,
+ .poweroff = ath6kl_sdio_pm_suspend,
+ .poweroff_late = ath6kl_sdio_pm_suspend_late,
+ .restore_early = ath6kl_sdio_pm_resume_early,
+ .restore = ath6kl_sdio_pm_resume,
+};
#define ATH6KL_SDIO_PM_OPS (&ath6kl_sdio_pm_ops)
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin
2015-11-23 0:15 ` [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin Steve deRosier
@ 2015-12-01 13:01 ` Kalle Valo
2015-12-06 0:19 ` kbuild test robot
1 sibling, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2015-12-01 13:01 UTC (permalink / raw)
To: Steve deRosier; +Cc: ath6kl, linux-wireless, Julian Calaby, Steve deRosier
Steve deRosier <derosier@gmail.com> writes:
> Many ath6k chips have a reset pin, usually labeled CHIP_PWD_L. This pin can
> be pulled low by the host processor to hold the wifi chip in reset. By
> holding the chip in reset, the lowest power consumption available can be
> achieved.
>
> This adds a module parameter so the ath6kl_sdio driver can control the
> CHIP_PWD_L pin if the implementer so desires. This code is only available
> if GPIOLIB is configured.
>
> Signed-off-by: Steve deRosier <steve.derosier@lairdtech.com>
I haven't reviewed the patch yet but at least it doesn't compile on
32bit x86:
CC [M] drivers/net/wireless/ath/ath6kl/sdio.o
drivers/net/wireless/ath/ath6kl/sdio.c:81:38: error: ‘ARCH_NR_GPIOS’
undeclared here (not in a function)
--
Kalle Valo
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin
2015-11-23 0:15 ` [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin Steve deRosier
2015-12-01 13:01 ` Kalle Valo
@ 2015-12-06 0:19 ` kbuild test robot
1 sibling, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2015-12-06 0:19 UTC (permalink / raw)
To: Steve deRosier
Cc: kbuild-all, Kalle Valo, ath6kl, linux-wireless, Julian Calaby,
Steve deRosier
[-- Attachment #1: Type: text/plain, Size: 1423 bytes --]
Hi Steve,
[auto build test ERROR on net-next/master]
[also build test ERROR on v4.4-rc3 next-20151203]
url: https://github.com/0day-ci/linux/commits/Steve-deRosier/ath6kl_sdio-add-control-of-CHIP_PWD_L-via-GPIO/20151123-123006
config: mips-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=mips
All errors (new ones prefixed by >>):
>> drivers/net/wireless/ath/ath6kl/sdio.c:81:38: error: 'ARCH_NR_GPIOS' undeclared here (not in a function)
static unsigned int reset_pwd_gpio = ARCH_NR_GPIOS;
^
vim +/ARCH_NR_GPIOS +81 drivers/net/wireless/ath/ath6kl/sdio.c
75 * spurious warning:
76 * "ath6kl_sdio: probe of mmc0:0001:1 failed with error -110"
77 *
78 * Time chosen experimentally, with padding
79 */
80 #define ATH6KL_MMC_PROBE_DELAY 150
> 81 static unsigned int reset_pwd_gpio = ARCH_NR_GPIOS;
82 #ifdef CONFIG_GPIOLIB
83 module_param(reset_pwd_gpio, uint, 0644);
84 MODULE_PARM_DESC(reset_pwd_gpio, "WIFI CHIP_PWD reset pin GPIO");
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 39732 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-12-06 0:21 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-23 0:15 [PATCH v3 0/2] ath6kl_sdio: add control of CHIP_PWD_L via GPIO Steve deRosier
2015-11-23 0:15 ` [PATCH v3 1/2] ath6kl_sdio: Add reset gpio module parameter for CHIP_PWD_L pin Steve deRosier
2015-12-01 13:01 ` Kalle Valo
2015-12-06 0:19 ` kbuild test robot
2015-11-23 0:15 ` [PATCH v3 2/2] ath6kl_sdio: Add power gpio reset feature into sdio driver for suspend Steve deRosier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).