Skip to content

Commit 04d46a7

Browse files
Srinivas-Kandagatlavinodkoul
authored andcommitted
soundwire: qcom: add in-band wake up interrupt support
Some of the Qualcomm SoundWire Controller instances like the ones that are connected to RX path along with Headset connections support Waking up Controller from Low power clock stop state using SoundWire In-band interrupt. SoundWire Slave on the bus would initiate this by pulling the data line high, while the clock is stopped. Add support to this wake up interrupt. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20220228172528.3489-4-srinivas.kandagatla@linaro.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent c7449e7 commit 04d46a7

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

drivers/soundwire/qcom.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/pm_runtime.h>
1515
#include <linux/regmap.h>
1616
#include <linux/slab.h>
17+
#include <linux/pm_wakeirq.h>
1718
#include <linux/slimbus.h>
1819
#include <linux/soundwire/sdw.h>
1920
#include <linux/soundwire/sdw_registers.h>
@@ -154,6 +155,7 @@ struct qcom_swrm_ctrl {
154155
u8 rd_cmd_id;
155156
int irq;
156157
unsigned int version;
158+
int wake_irq;
157159
int num_din_ports;
158160
int num_dout_ports;
159161
int cols_index;
@@ -503,6 +505,30 @@ static int qcom_swrm_enumerate(struct sdw_bus *bus)
503505
return 0;
504506
}
505507

508+
static irqreturn_t qcom_swrm_wake_irq_handler(int irq, void *dev_id)
509+
{
510+
struct qcom_swrm_ctrl *swrm = dev_id;
511+
int ret;
512+
513+
ret = pm_runtime_get_sync(swrm->dev);
514+
if (ret < 0 && ret != -EACCES) {
515+
dev_err_ratelimited(swrm->dev,
516+
"pm_runtime_get_sync failed in %s, ret %d\n",
517+
__func__, ret);
518+
pm_runtime_put_noidle(swrm->dev);
519+
}
520+
521+
if (swrm->wake_irq > 0) {
522+
if (!irqd_irq_disabled(irq_get_irq_data(swrm->wake_irq)))
523+
disable_irq_nosync(swrm->wake_irq);
524+
}
525+
526+
pm_runtime_mark_last_busy(swrm->dev);
527+
pm_runtime_put_autosuspend(swrm->dev);
528+
529+
return IRQ_HANDLED;
530+
}
531+
506532
static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
507533
{
508534
struct qcom_swrm_ctrl *swrm = dev_id;
@@ -1340,6 +1366,18 @@ static int qcom_swrm_probe(struct platform_device *pdev)
13401366
goto err_clk;
13411367
}
13421368

1369+
ctrl->wake_irq = of_irq_get(dev->of_node, 1);
1370+
if (ctrl->wake_irq > 0) {
1371+
ret = devm_request_threaded_irq(dev, ctrl->wake_irq, NULL,
1372+
qcom_swrm_wake_irq_handler,
1373+
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
1374+
"swr_wake_irq", ctrl);
1375+
if (ret) {
1376+
dev_err(dev, "Failed to request soundwire wake irq\n");
1377+
goto err_init;
1378+
}
1379+
}
1380+
13431381
ret = sdw_bus_master_add(&ctrl->bus, dev, dev->fwnode);
13441382
if (ret) {
13451383
dev_err(dev, "Failed to register Soundwire controller (%d)\n",
@@ -1424,6 +1462,11 @@ static int swrm_runtime_resume(struct device *dev)
14241462
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
14251463
int ret;
14261464

1465+
if (ctrl->wake_irq > 0) {
1466+
if (!irqd_irq_disabled(irq_get_irq_data(ctrl->wake_irq)))
1467+
disable_irq_nosync(ctrl->wake_irq);
1468+
}
1469+
14271470
clk_prepare_enable(ctrl->hclk);
14281471

14291472
if (ctrl->clock_stop_not_supported) {
@@ -1491,6 +1534,11 @@ static int __maybe_unused swrm_runtime_suspend(struct device *dev)
14911534

14921535
usleep_range(300, 305);
14931536

1537+
if (ctrl->wake_irq > 0) {
1538+
if (irqd_irq_disabled(irq_get_irq_data(ctrl->wake_irq)))
1539+
enable_irq(ctrl->wake_irq);
1540+
}
1541+
14941542
return 0;
14951543
}
14961544

0 commit comments

Comments
 (0)