Commit 4ed924fc authored by Zhengping Jiang's avatar Zhengping Jiang Committed by Luiz Augusto von Dentz
Browse files

Bluetooth: btmtksdio: enable bluetooth wakeup in system suspend



The BTMTKSDIO_BT_WAKE_ENABLED flag is set for bluetooth interrupt
during system suspend and increases wakeup count for bluetooth event.

Signed-off-by: default avatarZhengping Jiang <jiangzp@google.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent da06ff1f
Loading
Loading
Loading
Loading
+38 −6
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
#define BTMTKSDIO_FUNC_ENABLED		3
#define BTMTKSDIO_PATCH_ENABLED		4
#define BTMTKSDIO_HW_RESET_ACTIVE	5
#define BTMTKSDIO_BT_WAKE_ENABLED	6

struct mtkbtsdio_hdr {
	__le16	len;
@@ -554,7 +555,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
	sdio_claim_host(bdev->func);

	/* Disable interrupt */
	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);

	txrx_timeout = jiffies + 5 * HZ;

@@ -576,7 +577,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
		if ((int_status & FW_MAILBOX_INT) &&
		    bdev->data->chipid == 0x7921) {
			sdio_writel(bdev->func, PH2DSM0R_DRIVER_OWN,
				    MTK_REG_PH2DSM0R, 0);
				    MTK_REG_PH2DSM0R, NULL);
		}

		if (int_status & FW_OWN_BACK_INT)
@@ -608,7 +609,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
	} while (int_status || time_is_before_jiffies(txrx_timeout));

	/* Enable interrupt */
	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, 0);
	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);

	sdio_release_host(bdev->func);

@@ -620,8 +621,14 @@ static void btmtksdio_interrupt(struct sdio_func *func)
{
	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);

	if (test_bit(BTMTKSDIO_BT_WAKE_ENABLED, &bdev->tx_state)) {
		if (bdev->hdev->suspended)
			pm_wakeup_event(bdev->dev, 0);
		clear_bit(BTMTKSDIO_BT_WAKE_ENABLED, &bdev->tx_state);
	}

	/* Disable interrupt */
	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);

	schedule_work(&bdev->txrx_work);
}
@@ -1454,6 +1461,23 @@ static int btmtksdio_runtime_suspend(struct device *dev)
	return err;
}

static int btmtksdio_system_suspend(struct device *dev)
{
	struct sdio_func *func = dev_to_sdio_func(dev);
	struct btmtksdio_dev *bdev;

	bdev = sdio_get_drvdata(func);
	if (!bdev)
		return 0;

	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
		return 0;

	set_bit(BTMTKSDIO_BT_WAKE_ENABLED, &bdev->tx_state);

	return btmtksdio_runtime_suspend(dev);
}

static int btmtksdio_runtime_resume(struct device *dev)
{
	struct sdio_func *func = dev_to_sdio_func(dev);
@@ -1474,8 +1498,16 @@ static int btmtksdio_runtime_resume(struct device *dev)
	return err;
}

static UNIVERSAL_DEV_PM_OPS(btmtksdio_pm_ops, btmtksdio_runtime_suspend,
			    btmtksdio_runtime_resume, NULL);
static int btmtksdio_system_resume(struct device *dev)
{
	return btmtksdio_runtime_resume(dev);
}

static const struct dev_pm_ops btmtksdio_pm_ops = {
	SYSTEM_SLEEP_PM_OPS(btmtksdio_system_suspend, btmtksdio_system_resume)
	RUNTIME_PM_OPS(btmtksdio_runtime_suspend, btmtksdio_runtime_resume, NULL)
};

#define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops)
#else	/* CONFIG_PM */
#define BTMTKSDIO_PM_OPS NULL