* [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks
@ 2012-04-25 18:43 Bing Zhao
2012-05-03 0:29 ` Bing Zhao
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Bing Zhao @ 2012-04-25 18:43 UTC (permalink / raw)
To: linux-bluetooth
Cc: linux-wireless, Marcel Holtmann, Gustavo Padovan, Johan Hedberg,
Bing Zhao, Amitkumar Karwar
From: Amitkumar Karwar <akarwar@marvell.com>
Host sleep is activated using already configured host sleep
parameters in suspend handler and it is cancelled in resume
handler.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: remove '\n' at end of BT_DBG, BT_ERR. (Marcel Holtmann)
drivers/bluetooth/btmrvl_drv.h | 2 +
drivers/bluetooth/btmrvl_main.c | 3 +-
drivers/bluetooth/btmrvl_sdio.c | 100 +++++++++++++++++++++++++++++++++++++++
3 files changed, 104 insertions(+), 1 deletions(-)
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index 2c79e76..94f2d65 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -67,6 +67,7 @@ struct btmrvl_adapter {
u8 wakeup_tries;
wait_queue_head_t cmd_wait_q;
u8 cmd_complete;
+ bool is_suspended;
};
struct btmrvl_private {
@@ -142,6 +143,7 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
int btmrvl_enable_ps(struct btmrvl_private *priv);
int btmrvl_prepare_command(struct btmrvl_private *priv);
+int btmrvl_enable_hs(struct btmrvl_private *priv);
#ifdef CONFIG_DEBUG_FS
void btmrvl_debugfs_init(struct hci_dev *hdev);
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index a880537..681ca9d 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -262,7 +262,7 @@ int btmrvl_enable_ps(struct btmrvl_private *priv)
}
EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
-static int btmrvl_enable_hs(struct btmrvl_private *priv)
+int btmrvl_enable_hs(struct btmrvl_private *priv)
{
struct sk_buff *skb;
struct btmrvl_cmd *cmd;
@@ -298,6 +298,7 @@ static int btmrvl_enable_hs(struct btmrvl_private *priv)
return ret;
}
+EXPORT_SYMBOL_GPL(btmrvl_enable_hs);
int btmrvl_prepare_command(struct btmrvl_private *priv)
{
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index d7d8f83..a853244 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -1046,11 +1046,111 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
}
}
+static int btmrvl_sdio_suspend(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct btmrvl_sdio_card *card;
+ struct btmrvl_private *priv;
+ mmc_pm_flag_t pm_flags;
+ struct hci_dev *hcidev;
+
+ if (func) {
+ pm_flags = sdio_get_host_pm_caps(func);
+ BT_DBG("%s: suspend: PM flags = 0x%x", sdio_func_id(func),
+ pm_flags);
+ if (!(pm_flags & MMC_PM_KEEP_POWER)) {
+ BT_ERR("%s: cannot remain alive while suspended",
+ sdio_func_id(func));
+ return -ENOSYS;
+ }
+ card = sdio_get_drvdata(func);
+ if (!card || !card->priv) {
+ BT_ERR("card or priv structure is not valid");
+ return 0;
+ }
+ } else {
+ BT_ERR("sdio_func is not specified");
+ return 0;
+ }
+
+ priv = card->priv;
+
+ if (priv->adapter->hs_state != HS_ACTIVATED) {
+ if (btmrvl_enable_hs(priv)) {
+ BT_ERR("HS not actived, suspend failed!");
+ return -EBUSY;
+ }
+ }
+ hcidev = priv->btmrvl_dev.hcidev;
+ BT_DBG("%s: SDIO suspend", hcidev->name);
+ hci_suspend_dev(hcidev);
+ skb_queue_purge(&priv->adapter->tx_queue);
+
+ priv->adapter->is_suspended = true;
+
+ /* We will keep the power when hs enabled successfully */
+ if (priv->adapter->hs_state == HS_ACTIVATED) {
+ BT_DBG("suspend with MMC_PM_KEEP_POWER");
+ return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ } else {
+ BT_DBG("suspend without MMC_PM_KEEP_POWER");
+ return 0;
+ }
+}
+
+static int btmrvl_sdio_resume(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct btmrvl_sdio_card *card;
+ struct btmrvl_private *priv;
+ mmc_pm_flag_t pm_flags;
+ struct hci_dev *hcidev;
+
+ if (func) {
+ pm_flags = sdio_get_host_pm_caps(func);
+ BT_DBG("%s: resume: PM flags = 0x%x", sdio_func_id(func),
+ pm_flags);
+ card = sdio_get_drvdata(func);
+ if (!card || !card->priv) {
+ BT_ERR("card or priv structure is not valid");
+ return 0;
+ }
+ } else {
+ BT_ERR("sdio_func is not specified");
+ return 0;
+ }
+ priv = card->priv;
+
+ if (!priv->adapter->is_suspended) {
+ BT_DBG("device already resumed");
+ return 0;
+ }
+
+ priv->adapter->is_suspended = false;
+ hcidev = priv->btmrvl_dev.hcidev;
+ BT_DBG("%s: SDIO resume", hcidev->name);
+ hci_resume_dev(hcidev);
+ priv->hw_wakeup_firmware(priv);
+ priv->adapter->hs_state = HS_DEACTIVATED;
+ BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
+
+ return 0;
+}
+
+static const struct dev_pm_ops btmrvl_sdio_pm_ops = {
+ .suspend = btmrvl_sdio_suspend,
+ .resume = btmrvl_sdio_resume,
+};
+
static struct sdio_driver bt_mrvl_sdio = {
.name = "btmrvl_sdio",
.id_table = btmrvl_sdio_ids,
.probe = btmrvl_sdio_probe,
.remove = btmrvl_sdio_remove,
+ .drv = {
+ .owner = THIS_MODULE,
+ .pm = &btmrvl_sdio_pm_ops,
+ }
};
static int __init btmrvl_sdio_init_module(void)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks
2012-04-25 18:43 [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks Bing Zhao
@ 2012-05-03 0:29 ` Bing Zhao
2012-05-03 4:51 ` Marcel Holtmann
2012-05-03 5:22 ` Gustavo Padovan
2 siblings, 0 replies; 4+ messages in thread
From: Bing Zhao @ 2012-05-03 0:29 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo Padovan, linux-bluetooth@vger.kernel.org
Cc: linux-wireless@vger.kernel.org, Johan Hedberg, Amitkumar Karwar
Hi Marcel, Gustavo,
> From: Amitkumar Karwar <akarwar@marvell.com>
>=20
> Host sleep is activated using already configured host sleep
> parameters in suspend handler and it is cancelled in resume
> handler.
>=20
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> Signed-off-by: Bing Zhao <bzhao@marvell.com>
> ---
> v2: remove '\n' at end of BT_DBG, BT_ERR. (Marcel Holtmann)
Could you please review this v2 patch?
Thanks,
Bing
>=20
> drivers/bluetooth/btmrvl_drv.h | 2 +
> drivers/bluetooth/btmrvl_main.c | 3 +-
> drivers/bluetooth/btmrvl_sdio.c | 100 +++++++++++++++++++++++++++++++++=
++++++
> 3 files changed, 104 insertions(+), 1 deletions(-)
>=20
> diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_dr=
v.h
> index 2c79e76..94f2d65 100644
> --- a/drivers/bluetooth/btmrvl_drv.h
> +++ b/drivers/bluetooth/btmrvl_drv.h
> @@ -67,6 +67,7 @@ struct btmrvl_adapter {
> u8 wakeup_tries;
> wait_queue_head_t cmd_wait_q;
> u8 cmd_complete;
> + bool is_suspended;
> };
>=20
> struct btmrvl_private {
> @@ -142,6 +143,7 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private =
*priv, int subcmd);
> int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
> int btmrvl_enable_ps(struct btmrvl_private *priv);
> int btmrvl_prepare_command(struct btmrvl_private *priv);
> +int btmrvl_enable_hs(struct btmrvl_private *priv);
>=20
> #ifdef CONFIG_DEBUG_FS
> void btmrvl_debugfs_init(struct hci_dev *hdev);
> diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_m=
ain.c
> index a880537..681ca9d 100644
> --- a/drivers/bluetooth/btmrvl_main.c
> +++ b/drivers/bluetooth/btmrvl_main.c
> @@ -262,7 +262,7 @@ int btmrvl_enable_ps(struct btmrvl_private *priv)
> }
> EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
>=20
> -static int btmrvl_enable_hs(struct btmrvl_private *priv)
> +int btmrvl_enable_hs(struct btmrvl_private *priv)
> {
> struct sk_buff *skb;
> struct btmrvl_cmd *cmd;
> @@ -298,6 +298,7 @@ static int btmrvl_enable_hs(struct btmrvl_private *pr=
iv)
>=20
> return ret;
> }
> +EXPORT_SYMBOL_GPL(btmrvl_enable_hs);
>=20
> int btmrvl_prepare_command(struct btmrvl_private *priv)
> {
> diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_s=
dio.c
> index d7d8f83..a853244 100644
> --- a/drivers/bluetooth/btmrvl_sdio.c
> +++ b/drivers/bluetooth/btmrvl_sdio.c
> @@ -1046,11 +1046,111 @@ static void btmrvl_sdio_remove(struct sdio_func =
*func)
> }
> }
>=20
> +static int btmrvl_sdio_suspend(struct device *dev)
> +{
> + struct sdio_func *func =3D dev_to_sdio_func(dev);
> + struct btmrvl_sdio_card *card;
> + struct btmrvl_private *priv;
> + mmc_pm_flag_t pm_flags;
> + struct hci_dev *hcidev;
> +
> + if (func) {
> + pm_flags =3D sdio_get_host_pm_caps(func);
> + BT_DBG("%s: suspend: PM flags =3D 0x%x", sdio_func_id(func),
> + pm_flags);
> + if (!(pm_flags & MMC_PM_KEEP_POWER)) {
> + BT_ERR("%s: cannot remain alive while suspended",
> + sdio_func_id(func));
> + return -ENOSYS;
> + }
> + card =3D sdio_get_drvdata(func);
> + if (!card || !card->priv) {
> + BT_ERR("card or priv structure is not valid");
> + return 0;
> + }
> + } else {
> + BT_ERR("sdio_func is not specified");
> + return 0;
> + }
> +
> + priv =3D card->priv;
> +
> + if (priv->adapter->hs_state !=3D HS_ACTIVATED) {
> + if (btmrvl_enable_hs(priv)) {
> + BT_ERR("HS not actived, suspend failed!");
> + return -EBUSY;
> + }
> + }
> + hcidev =3D priv->btmrvl_dev.hcidev;
> + BT_DBG("%s: SDIO suspend", hcidev->name);
> + hci_suspend_dev(hcidev);
> + skb_queue_purge(&priv->adapter->tx_queue);
> +
> + priv->adapter->is_suspended =3D true;
> +
> + /* We will keep the power when hs enabled successfully */
> + if (priv->adapter->hs_state =3D=3D HS_ACTIVATED) {
> + BT_DBG("suspend with MMC_PM_KEEP_POWER");
> + return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
> + } else {
> + BT_DBG("suspend without MMC_PM_KEEP_POWER");
> + return 0;
> + }
> +}
> +
> +static int btmrvl_sdio_resume(struct device *dev)
> +{
> + struct sdio_func *func =3D dev_to_sdio_func(dev);
> + struct btmrvl_sdio_card *card;
> + struct btmrvl_private *priv;
> + mmc_pm_flag_t pm_flags;
> + struct hci_dev *hcidev;
> +
> + if (func) {
> + pm_flags =3D sdio_get_host_pm_caps(func);
> + BT_DBG("%s: resume: PM flags =3D 0x%x", sdio_func_id(func),
> + pm_flags);
> + card =3D sdio_get_drvdata(func);
> + if (!card || !card->priv) {
> + BT_ERR("card or priv structure is not valid");
> + return 0;
> + }
> + } else {
> + BT_ERR("sdio_func is not specified");
> + return 0;
> + }
> + priv =3D card->priv;
> +
> + if (!priv->adapter->is_suspended) {
> + BT_DBG("device already resumed");
> + return 0;
> + }
> +
> + priv->adapter->is_suspended =3D false;
> + hcidev =3D priv->btmrvl_dev.hcidev;
> + BT_DBG("%s: SDIO resume", hcidev->name);
> + hci_resume_dev(hcidev);
> + priv->hw_wakeup_firmware(priv);
> + priv->adapter->hs_state =3D HS_DEACTIVATED;
> + BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
> +
> + return 0;
> +}
> +
> +static const struct dev_pm_ops btmrvl_sdio_pm_ops =3D {
> + .suspend =3D btmrvl_sdio_suspend,
> + .resume =3D btmrvl_sdio_resume,
> +};
> +
> static struct sdio_driver bt_mrvl_sdio =3D {
> .name =3D "btmrvl_sdio",
> .id_table =3D btmrvl_sdio_ids,
> .probe =3D btmrvl_sdio_probe,
> .remove =3D btmrvl_sdio_remove,
> + .drv =3D {
> + .owner =3D THIS_MODULE,
> + .pm =3D &btmrvl_sdio_pm_ops,
> + }
> };
>=20
> static int __init btmrvl_sdio_init_module(void)
> --
> 1.7.0.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks
2012-04-25 18:43 [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks Bing Zhao
2012-05-03 0:29 ` Bing Zhao
@ 2012-05-03 4:51 ` Marcel Holtmann
2012-05-03 5:22 ` Gustavo Padovan
2 siblings, 0 replies; 4+ messages in thread
From: Marcel Holtmann @ 2012-05-03 4:51 UTC (permalink / raw)
To: Bing Zhao
Cc: linux-bluetooth, linux-wireless, Gustavo Padovan, Johan Hedberg,
Amitkumar Karwar
Hi Bing,
> Host sleep is activated using already configured host sleep
> parameters in suspend handler and it is cancelled in resume
> handler.
>
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> Signed-off-by: Bing Zhao <bzhao@marvell.com>
> ---
> v2: remove '\n' at end of BT_DBG, BT_ERR. (Marcel Holtmann)
>
> drivers/bluetooth/btmrvl_drv.h | 2 +
> drivers/bluetooth/btmrvl_main.c | 3 +-
> drivers/bluetooth/btmrvl_sdio.c | 100 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 104 insertions(+), 1 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks
2012-04-25 18:43 [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks Bing Zhao
2012-05-03 0:29 ` Bing Zhao
2012-05-03 4:51 ` Marcel Holtmann
@ 2012-05-03 5:22 ` Gustavo Padovan
2 siblings, 0 replies; 4+ messages in thread
From: Gustavo Padovan @ 2012-05-03 5:22 UTC (permalink / raw)
To: Bing Zhao
Cc: linux-bluetooth, linux-wireless, Marcel Holtmann, Johan Hedberg,
Amitkumar Karwar
Hi Bing,
* Bing Zhao <bzhao@marvell.com> [2012-04-25 11:43:54 -0700]:
> From: Amitkumar Karwar <akarwar@marvell.com>
>
> Host sleep is activated using already configured host sleep
> parameters in suspend handler and it is cancelled in resume
> handler.
>
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> Signed-off-by: Bing Zhao <bzhao@marvell.com>
> ---
> v2: remove '\n' at end of BT_DBG, BT_ERR. (Marcel Holtmann)
>
> drivers/bluetooth/btmrvl_drv.h | 2 +
> drivers/bluetooth/btmrvl_main.c | 3 +-
> drivers/bluetooth/btmrvl_sdio.c | 100 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 104 insertions(+), 1 deletions(-)
Patch has been applied to bluetooth-next. Thanks.
Gustavo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-05-03 5:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-25 18:43 [PATCH 2/2 v2] Bluetooth: btmrvl: add support for SDIO suspend/resume callbacks Bing Zhao
2012-05-03 0:29 ` Bing Zhao
2012-05-03 4:51 ` Marcel Holtmann
2012-05-03 5:22 ` Gustavo Padovan
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).