aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2011-07-04 13:15:19 -0400
committerPeter Ujfalusi <peter.ujfalusi@ti.com>2011-07-07 07:23:25 -0400
commitd20e1d21fd0c398a8beb170beacf8e2ca839844c (patch)
tree08f292359e01b4069e6042d958c12384fbce64ed
parent2a433b9daff58c8ff231b879242a586371acc93f (diff)
MFD: twl6040: Demand valid interrupt configuration
In order to operate correctly twl6040 needs correct interrupt configuration. The slave drivers (vibra, and ASoC codec) will refuse to probe, if the interrupt configuration is not correct. In this way some checks can be removed from the code. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Reviewed-by: Felipe Balbi <balbi@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/twl6040-core.c42
-rw-r--r--drivers/mfd/twl6040-irq.c16
2 files changed, 22 insertions, 36 deletions
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index 471f4895fb90..f71bb147d11c 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -459,6 +459,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
459 return -EINVAL; 459 return -EINVAL;
460 } 460 }
461 461
462 /* In order to operate correctly we need valid interrupt config */
463 if (!pdata->naudint_irq || !pdata->irq_base) {
464 dev_err(&pdev->dev, "Invalid IRQ configuration\n");
465 return -EINVAL;
466 }
467
462 twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); 468 twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
463 if (!twl6040) 469 if (!twl6040)
464 return -ENOMEM; 470 return -ENOMEM;
@@ -491,20 +497,18 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
491 if (twl6040->rev == TWL6040_REV_ES1_0) 497 if (twl6040->rev == TWL6040_REV_ES1_0)
492 twl6040->audpwron = -EINVAL; 498 twl6040->audpwron = -EINVAL;
493 499
494 if (twl6040->irq) { 500 /* codec interrupt */
495 /* codec interrupt */ 501 ret = twl6040_irq_init(twl6040);
496 ret = twl6040_irq_init(twl6040); 502 if (ret)
497 if (ret) 503 goto gpio2_err;
498 goto gpio2_err; 504
499 505 ret = twl6040_request_irq(twl6040, TWL6040_IRQ_READY,
500 ret = twl6040_request_irq(twl6040, TWL6040_IRQ_READY, 506 twl6040_naudint_handler, 0,
501 twl6040_naudint_handler, 0, 507 "twl6040_irq_ready", twl6040);
502 "twl6040_irq_ready", twl6040); 508 if (ret) {
503 if (ret) { 509 dev_err(twl6040->dev, "READY IRQ request failed: %d\n",
504 dev_err(twl6040->dev, "READY IRQ request failed: %d\n", 510 ret);
505 ret); 511 goto irq_err;
506 goto irq_err;
507 }
508 } 512 }
509 513
510 /* dual-access registers controlled by I2C only */ 514 /* dual-access registers controlled by I2C only */
@@ -553,11 +557,9 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
553 return 0; 557 return 0;
554 558
555mfd_err: 559mfd_err:
556 if (twl6040->irq) 560 twl6040_free_irq(twl6040, TWL6040_IRQ_READY, twl6040);
557 twl6040_free_irq(twl6040, TWL6040_IRQ_READY, twl6040);
558irq_err: 561irq_err:
559 if (twl6040->irq) 562 twl6040_irq_exit(twl6040);
560 twl6040_irq_exit(twl6040);
561gpio2_err: 563gpio2_err:
562 if (gpio_is_valid(twl6040->audpwron)) 564 if (gpio_is_valid(twl6040->audpwron))
563 gpio_free(twl6040->audpwron); 565 gpio_free(twl6040->audpwron);
@@ -579,9 +581,7 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
579 gpio_free(twl6040->audpwron); 581 gpio_free(twl6040->audpwron);
580 582
581 twl6040_free_irq(twl6040, TWL6040_IRQ_READY, twl6040); 583 twl6040_free_irq(twl6040, TWL6040_IRQ_READY, twl6040);
582 584 twl6040_irq_exit(twl6040);
583 if (twl6040->irq)
584 twl6040_irq_exit(twl6040);
585 585
586 mfd_remove_devices(&pdev->dev); 586 mfd_remove_devices(&pdev->dev);
587 platform_set_drvdata(pdev, NULL); 587 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/mfd/twl6040-irq.c b/drivers/mfd/twl6040-irq.c
index 938053541520..b3f8ddaa28a8 100644
--- a/drivers/mfd/twl6040-irq.c
+++ b/drivers/mfd/twl6040-irq.c
@@ -148,19 +148,6 @@ int twl6040_irq_init(struct twl6040 *twl6040)
148 twl6040->irq_masks_cache = TWL6040_ALLINT_MSK; 148 twl6040->irq_masks_cache = TWL6040_ALLINT_MSK;
149 twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK); 149 twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK);
150 150
151 if (!twl6040->irq) {
152 dev_warn(twl6040->dev,
153 "no interrupt specified, no interrupts\n");
154 twl6040->irq_base = 0;
155 return 0;
156 }
157
158 if (!twl6040->irq_base) {
159 dev_err(twl6040->dev,
160 "no interrupt base specified, no interrupts\n");
161 return 0;
162 }
163
164 /* Register them with genirq */ 151 /* Register them with genirq */
165 for (cur_irq = twl6040->irq_base; 152 for (cur_irq = twl6040->irq_base;
166 cur_irq < twl6040->irq_base + ARRAY_SIZE(twl6040_irqs); 153 cur_irq < twl6040->irq_base + ARRAY_SIZE(twl6040_irqs);
@@ -199,7 +186,6 @@ EXPORT_SYMBOL(twl6040_irq_init);
199 186
200void twl6040_irq_exit(struct twl6040 *twl6040) 187void twl6040_irq_exit(struct twl6040 *twl6040)
201{ 188{
202 if (twl6040->irq) 189 free_irq(twl6040->irq, twl6040);
203 free_irq(twl6040->irq, twl6040);
204} 190}
205EXPORT_SYMBOL(twl6040_irq_exit); 191EXPORT_SYMBOL(twl6040_irq_exit);