soc: swr-mstr: Add wakeup irq support from afe using event notifier
Register and handle swr wakeup irq from afe, using aud event notifier codec interrupts during clock stop mode. Change-Id: I76d250adcaa8af4a413f6274482beb5a3469601d Signed-off-by: Ramprasad Katkam <katkam@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
68765abe11
commit
f0128ef169
@@ -1296,6 +1296,25 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void swrm_wakeup_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct swr_mstr_ctrl *swrm;
|
||||||
|
|
||||||
|
swrm = container_of(work, struct swr_mstr_ctrl,
|
||||||
|
wakeup_work);
|
||||||
|
if (!swrm || !(swrm->dev)) {
|
||||||
|
pr_err("%s: swrm or dev is null\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pm_runtime_get_sync(swrm->dev);
|
||||||
|
|
||||||
|
swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0xF,
|
||||||
|
SWRS_SCP_INT_STATUS_MASK_1);
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(swrm->dev);
|
||||||
|
pm_runtime_put_autosuspend(swrm->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum)
|
static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
@@ -1425,29 +1444,41 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int swrm_event_notify(struct notifier_block *self,
|
static int swrm_event_notify(struct notifier_block *self,
|
||||||
unsigned long action, void *data)
|
unsigned long action, void *data)
|
||||||
{
|
{
|
||||||
struct swr_mstr_ctrl *swrm = container_of(self, struct swr_mstr_ctrl,
|
struct swr_mstr_ctrl *swrm = container_of(self, struct swr_mstr_ctrl,
|
||||||
event_notifier);
|
event_notifier);
|
||||||
if (!swrm || !swrm->pdev) {
|
|
||||||
pr_err("%s: swrm or pdev is NULL\n", __func__);
|
if (!swrm || !(swrm->dev)) {
|
||||||
|
pr_err("%s: swrm or dev is NULL\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (action != MSM_AUD_DC_EVENT) {
|
switch (action) {
|
||||||
dev_err(&swrm->pdev->dev, "%s: invalid event type: %lu\n",
|
case MSM_AUD_DC_EVENT:
|
||||||
|
schedule_work(&(swrm->dc_presence_work));
|
||||||
|
break;
|
||||||
|
case SWR_WAKE_IRQ_EVENT:
|
||||||
|
if (swrm->wakeup_req)
|
||||||
|
schedule_work(&swrm->wakeup_work);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(swrm->dev, "%s: invalid event type: %lu\n",
|
||||||
__func__, action);
|
__func__, action);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_work(&(swrm->dc_presence_work));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void swrm_notify_work_fn(struct work_struct *work)
|
static void swrm_notify_work_fn(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct swr_mstr_ctrl *swrm = container_of(work, struct swr_mstr_ctrl,
|
struct swr_mstr_ctrl *swrm = container_of(work, struct swr_mstr_ctrl,
|
||||||
dc_presence_work);
|
dc_presence_work);
|
||||||
|
|
||||||
|
if (!swrm || !swrm->pdev) {
|
||||||
|
pr_err("%s: swrm or pdev is NULL\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
swrm_wcd_notify(swrm->pdev, SWR_DEVICE_DOWN, NULL);
|
swrm_wcd_notify(swrm->pdev, SWR_DEVICE_DOWN, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1466,6 +1497,7 @@ static int swrm_probe(struct platform_device *pdev)
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_memory_fail;
|
goto err_memory_fail;
|
||||||
}
|
}
|
||||||
|
swrm->pdev = pdev;
|
||||||
swrm->dev = &pdev->dev;
|
swrm->dev = &pdev->dev;
|
||||||
platform_set_drvdata(pdev, swrm);
|
platform_set_drvdata(pdev, swrm);
|
||||||
swr_set_ctrl_data(&swrm->master, swrm);
|
swr_set_ctrl_data(&swrm->master, swrm);
|
||||||
@@ -1622,6 +1654,12 @@ static int swrm_probe(struct platform_device *pdev)
|
|||||||
goto err_pdata_fail;
|
goto err_pdata_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (of_property_read_u32(swrm->dev->of_node,
|
||||||
|
"qcom,swr-wakeup-required", &swrm->wakeup_req)) {
|
||||||
|
swrm->wakeup_req = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (swrm->reg_irq) {
|
if (swrm->reg_irq) {
|
||||||
ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm,
|
ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm,
|
||||||
SWR_IRQ_REGISTER);
|
SWR_IRQ_REGISTER);
|
||||||
@@ -1673,6 +1711,7 @@ static int swrm_probe(struct platform_device *pdev)
|
|||||||
swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
|
swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
|
||||||
|
|
||||||
mutex_unlock(&swrm->mlock);
|
mutex_unlock(&swrm->mlock);
|
||||||
|
INIT_WORK(&swrm->wakeup_work, swrm_wakeup_work);
|
||||||
|
|
||||||
if (pdev->dev.of_node)
|
if (pdev->dev.of_node)
|
||||||
of_register_swr_devices(&swrm->master);
|
of_register_swr_devices(&swrm->master);
|
||||||
@@ -1768,6 +1807,11 @@ static int swrm_runtime_resume(struct device *dev)
|
|||||||
mutex_lock(&swrm->reslock);
|
mutex_lock(&swrm->reslock);
|
||||||
if ((swrm->state == SWR_MSTR_PAUSE) ||
|
if ((swrm->state == SWR_MSTR_PAUSE) ||
|
||||||
(swrm->state == SWR_MSTR_DOWN)) {
|
(swrm->state == SWR_MSTR_DOWN)) {
|
||||||
|
if (swrm->clk_stop_mode0_supp && swrm->wakeup_req) {
|
||||||
|
msm_aud_evt_blocking_notifier_call_chain(
|
||||||
|
SWR_WAKE_IRQ_DEREGISTER, (void *)swrm);
|
||||||
|
}
|
||||||
|
|
||||||
if (swrm->state == SWR_MSTR_DOWN) {
|
if (swrm->state == SWR_MSTR_DOWN) {
|
||||||
if (swrm_clk_request(swrm, true))
|
if (swrm_clk_request(swrm, true))
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -1840,6 +1884,9 @@ static int swrm_runtime_suspend(struct device *dev)
|
|||||||
swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF,
|
swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF,
|
||||||
SWRS_SCP_CONTROL);
|
SWRS_SCP_CONTROL);
|
||||||
usleep_range(100, 105);
|
usleep_range(100, 105);
|
||||||
|
if (swrm->wakeup_req)
|
||||||
|
msm_aud_evt_blocking_notifier_call_chain(
|
||||||
|
SWR_WAKE_IRQ_REGISTER, (void *)swrm);
|
||||||
}
|
}
|
||||||
swrm_clk_request(swrm, false);
|
swrm_clk_request(swrm, false);
|
||||||
}
|
}
|
||||||
|
@@ -146,6 +146,8 @@ struct swr_mstr_ctrl {
|
|||||||
port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT];
|
port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT];
|
||||||
int swr_irq;
|
int swr_irq;
|
||||||
u32 clk_stop_mode0_supp;
|
u32 clk_stop_mode0_supp;
|
||||||
|
struct work_struct wakeup_work;
|
||||||
|
u32 wakeup_req;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SWR_WCD_CTRL_H */
|
#endif /* _SWR_WCD_CTRL_H */
|
||||||
|
Reference in New Issue
Block a user