aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2016-05-20 11:10:26 -0400
committerMark Brown <broonie@kernel.org>2016-06-02 19:41:15 -0400
commitccc12561926c0bef9a40865db93b926a0927e93f (patch)
tree2034ef3c4af60b796092465a89cec69ff859f0a2 /drivers/base
parent1a695a905c18548062509178b98bc91e67510864 (diff)
regmap: irq: Add support to call client specific pre/post interrupt service
Regmap irq implements the generic interrupt service routine which is common for most of devices. Some devices, like MAX77620, MAX20024 needs the special handling before and after servicing the interrupt as generic. For the example, MAX77620 programming guidelines for interrupt servicing says: 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM. 2. Read IRQTOP and service the interrupt accordingly. 3. Once all interrupts has been checked and serviced, the interrupt service routine un-masks the hardware interrupt line by clearing GLBLM. The step (2) is implemented in regmap irq as generic routine. For step (1) and (3), add callbacks from regmap irq to client driver to handle chip specific configurations. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap-irq.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 26f799e71c82..ec262476d043 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -268,13 +268,16 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
268 bool handled = false; 268 bool handled = false;
269 u32 reg; 269 u32 reg;
270 270
271 if (chip->handle_pre_irq)
272 chip->handle_pre_irq(chip->irq_drv_data);
273
271 if (chip->runtime_pm) { 274 if (chip->runtime_pm) {
272 ret = pm_runtime_get_sync(map->dev); 275 ret = pm_runtime_get_sync(map->dev);
273 if (ret < 0) { 276 if (ret < 0) {
274 dev_err(map->dev, "IRQ thread failed to resume: %d\n", 277 dev_err(map->dev, "IRQ thread failed to resume: %d\n",
275 ret); 278 ret);
276 pm_runtime_put(map->dev); 279 pm_runtime_put(map->dev);
277 return IRQ_NONE; 280 goto exit;
278 } 281 }
279 } 282 }
280 283
@@ -296,7 +299,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
296 if (ret != 0) { 299 if (ret != 0) {
297 dev_err(map->dev, "Failed to read IRQ status: %d\n", 300 dev_err(map->dev, "Failed to read IRQ status: %d\n",
298 ret); 301 ret);
299 return IRQ_NONE; 302 goto exit;
300 } 303 }
301 304
302 for (i = 0; i < data->chip->num_regs; i++) { 305 for (i = 0; i < data->chip->num_regs; i++) {
@@ -312,7 +315,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
312 break; 315 break;
313 default: 316 default:
314 BUG(); 317 BUG();
315 return IRQ_NONE; 318 goto exit;
316 } 319 }
317 } 320 }
318 321
@@ -329,7 +332,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
329 ret); 332 ret);
330 if (chip->runtime_pm) 333 if (chip->runtime_pm)
331 pm_runtime_put(map->dev); 334 pm_runtime_put(map->dev);
332 return IRQ_NONE; 335 goto exit;
333 } 336 }
334 } 337 }
335 } 338 }
@@ -365,6 +368,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
365 if (chip->runtime_pm) 368 if (chip->runtime_pm)
366 pm_runtime_put(map->dev); 369 pm_runtime_put(map->dev);
367 370
371exit:
372 if (chip->handle_post_irq)
373 chip->handle_post_irq(chip->irq_drv_data);
374
368 if (handled) 375 if (handled)
369 return IRQ_HANDLED; 376 return IRQ_HANDLED;
370 else 377 else