From: Dmitry Shmidt Date: Fri, 17 Sep 2010 21:38:25 +0000 (-0700) Subject: misc: max9635: Fix unbalanced enable_irq() call X-Git-Tag: firefly_0821_release~9834^2~547 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dd2c450118be2195e55b3be21a2a172f77eb1b9c;p=firefly-linux-kernel-4.4.55.git misc: max9635: Fix unbalanced enable_irq() call Signed-off-by: Dmitry Shmidt --- diff --git a/drivers/misc/max9635.c b/drivers/misc/max9635.c index 9e724ee8bc99..2a8b06ca5b21 100644 --- a/drivers/misc/max9635.c +++ b/drivers/misc/max9635.c @@ -29,6 +29,7 @@ #include #include #include +#include #define DEBUG 1 @@ -59,7 +60,8 @@ struct max9635_data { struct max9635_platform_data *als_pdata; struct max9635_zone_conv max9635_zone_info[255]; atomic_t enabled; - int irq; + spinlock_t irq_lock; + int cur_irq_state; }; struct max9635_data *max9635_misc_data; @@ -183,11 +185,26 @@ init_failed: return -EINVAL; } +static void max9635_irq_enable(struct max9635_data *als_data, int enable) +{ + unsigned long flags; + + spin_lock_irqsave(&als_data->irq_lock, flags); + if (als_data->cur_irq_state != enable) { + if (enable) + enable_irq(als_data->client->irq); + else + disable_irq_nosync(als_data->client->irq); + als_data->cur_irq_state = enable; + } + spin_unlock_irqrestore(&als_data->irq_lock, flags); +} + static irqreturn_t max9635_irq_handler(int irq, void *dev) { struct max9635_data *als_data = dev; - disable_irq_nosync(als_data->client->irq); + max9635_irq_enable(als_data, 0); schedule_delayed_work(&als_data->working_queue, 0); return IRQ_HANDLED; @@ -277,7 +294,7 @@ static int max9635_report_input(struct max9635_data *als_data) __func__, ret); return -1; } - enable_irq(als_data->client->irq); + max9635_irq_enable(als_data, 1); return ret; } @@ -523,6 +540,9 @@ static int max9635_probe(struct i2c_client *client, goto err_reg_init_failed; } + spin_lock_init(&als_data->irq_lock); + als_data->cur_irq_state = 1; + error = request_irq(als_data->client->irq, max9635_irq_handler, IRQF_TRIGGER_FALLING, MAX9635_NAME, als_data); if (error != 0) { @@ -541,7 +561,7 @@ static int max9635_probe(struct i2c_client *client, goto err_create_registers_file_failed; } #endif - disable_irq_nosync(als_data->client->irq); + max9635_irq_enable(als_data, 0); schedule_delayed_work(&als_data->working_queue, 0); return 0; @@ -583,7 +603,7 @@ static int max9635_suspend(struct i2c_client *client, pm_message_t mesg) if (max9635_debug) pr_info("%s: Suspending\n", __func__); - disable_irq_nosync(als_data->client->irq); + max9635_irq_enable(als_data, 0); cancel_delayed_work_sync(&als_data->working_queue); if (atomic_read(&als_data->enabled) == 1)