Currently irq is registered when i2c driver is loaded, it is unnecessary when component is unused. Initialize irq only when we probe ASoC component. Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@xxxxxxxxxxxxxxx> Reviewed-by: Cezary Rojewski <cezary.rojewski@xxxxxxxxx> --- sound/soc/codecs/rt286.c | 44 ++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 0534a073ee69..02a41c915776 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -945,13 +945,22 @@ static irqreturn_t rt286_irq(int irq, void *data) static int rt286_probe(struct snd_soc_component *component) { struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); + int ret; rt286->component = component; INIT_DELAYED_WORK(&rt286->jack_detect_work, rt286_jack_detect_work); - if (rt286->i2c->irq) - schedule_delayed_work(&rt286->jack_detect_work, - msecs_to_jiffies(50)); + if (rt286->i2c->irq) { + ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); + if (ret) { + dev_err(&rt286->i2c->dev, "Failed to reguest IRQ: %d\n", ret); + return ret; + } + + schedule_delayed_work(&rt286->jack_detect_work, msecs_to_jiffies(50)); + } + return 0; } @@ -959,7 +968,12 @@ static void rt286_remove(struct snd_soc_component *component) { struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); - cancel_delayed_work_sync(&rt286->jack_detect_work); + if (rt286->i2c->irq) { + cancel_delayed_work_sync(&rt286->jack_detect_work); + + disable_irq(rt286->i2c->irq); + free_irq(rt286->i2c->irq, rt286); + } } #ifdef CONFIG_PM @@ -1232,16 +1246,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c) RT286_GPIO_CTRL, 0xc, 0x8); } - if (rt286->i2c->irq) { - ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); - if (ret != 0) { - dev_err(&i2c->dev, - "Failed to reguest IRQ: %d\n", ret); - return ret; - } - } - ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_rt286, rt286_dai, ARRAY_SIZE(rt286_dai)); @@ -1249,24 +1253,12 @@ static int rt286_i2c_probe(struct i2c_client *i2c) return ret; } -static int rt286_i2c_remove(struct i2c_client *i2c) -{ - struct rt286_priv *rt286 = i2c_get_clientdata(i2c); - - if (i2c->irq) - free_irq(i2c->irq, rt286); - - return 0; -} - - static struct i2c_driver rt286_i2c_driver = { .driver = { .name = "rt286", .acpi_match_table = ACPI_PTR(rt286_acpi_match), }, .probe_new = rt286_i2c_probe, - .remove = rt286_i2c_remove, .id_table = rt286_i2c_id, }; -- 2.25.1