From df38c3eb18c0bda3c665bc19980d7f66414a7b3a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 11 Mar 2019 17:10:23 +0530 Subject: [PATCH] soc: swr: Add wakeup source for swr device Voice call over headset does not disconnect on button press while device is in suspend state. This is because inband interrupt is not made wakeup capable. Make inband interrupt for swr tx as wakeup capable. Also add wakeup source for swr device. Change-Id: I5f2751672675bc8d62c4d2bfbbd651e640723d52 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 23 ++++++++++++++++++++++- soc/swr-mstr-ctrl.h | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 8d82ff1ec775..722501ab1f25 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2055,6 +2055,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->slave_status = 0; swrm->num_rx_chs = 0; swrm->clk_ref_count = 0; + swrm->swr_irq_wakeup_capable = 0; swrm->mclk_freq = MCLK_FREQ; swrm->dev_up = true; swrm->state = SWR_MSTR_UP; @@ -2107,7 +2108,15 @@ static int swrm_probe(struct platform_device *pdev) } } - + /* Make inband tx interrupts as wakeup capable for slave irq */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,swr-mstr-irq-wakeup-capable", + &swrm->swr_irq_wakeup_capable); + if (ret) + dev_dbg(swrm->dev, "%s: swrm irq wakeup capable not defined\n", + __func__); + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 1); ret = swr_register_master(&swrm->master); if (ret) { dev_err(&pdev->dev, "%s: error adding swr master\n", __func__); @@ -2152,6 +2161,13 @@ static int swrm_probe(struct platform_device *pdev) (void *) "swrm_reg_dump", &swrm_debug_ops); } + + ret = device_init_wakeup(swrm->dev, true); + if (ret) { + dev_err(swrm->dev, "Device wakeup init failed: %d\n", ret); + goto err_irq_wakeup_fail; + } + pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_active(&pdev->dev); @@ -2163,6 +2179,8 @@ static int swrm_probe(struct platform_device *pdev) msm_aud_evt_register_client(&swrm->event_notifier); return 0; +err_irq_wakeup_fail: + device_init_wakeup(swrm->dev, false); err_mstr_fail: if (swrm->reg_irq) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, @@ -2194,11 +2212,14 @@ static int swrm_remove(struct platform_device *pdev) free_irq(swrm->irq, swrm); else if (swrm->wake_irq > 0) free_irq(swrm->wake_irq, swrm); + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 0); cancel_work_sync(&swrm->wakeup_work); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); swr_unregister_master(&swrm->master); msm_aud_evt_unregister_client(&swrm->event_notifier); + device_init_wakeup(swrm->dev, false); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->iolock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index fab66c39d26c..6ae3febfbce0 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -155,6 +155,7 @@ struct swr_mstr_ctrl { u32 intr_mask; struct port_params **port_param; u8 num_usecase; + u32 swr_irq_wakeup_capable; }; #endif /* _SWR_WCD_CTRL_H */