aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/88pm860x-core.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 72bf290bd020..5b56fe8250b4 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -15,6 +15,7 @@
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/irqdomain.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/regmap.h> 20#include <linux/regmap.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -520,15 +521,12 @@ static void pm860x_irq_sync_unlock(struct irq_data *data)
520 521
521static void pm860x_irq_enable(struct irq_data *data) 522static void pm860x_irq_enable(struct irq_data *data)
522{ 523{
523 struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); 524 pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
524 pm860x_irqs[data->irq - chip->irq_base].enable
525 = pm860x_irqs[data->irq - chip->irq_base].offs;
526} 525}
527 526
528static void pm860x_irq_disable(struct irq_data *data) 527static void pm860x_irq_disable(struct irq_data *data)
529{ 528{
530 struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); 529 pm860x_irqs[data->hwirq].enable = 0;
531 pm860x_irqs[data->irq - chip->irq_base].enable = 0;
532} 530}
533 531
534static struct irq_chip pm860x_irq_chip = { 532static struct irq_chip pm860x_irq_chip = {
@@ -539,6 +537,25 @@ static struct irq_chip pm860x_irq_chip = {
539 .irq_disable = pm860x_irq_disable, 537 .irq_disable = pm860x_irq_disable,
540}; 538};
541 539
540static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
541 irq_hw_number_t hw)
542{
543 irq_set_chip_data(virq, d->host_data);
544 irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
545 irq_set_nested_thread(virq, 1);
546#ifdef CONFIG_ARM
547 set_irq_flags(virq, IRQF_VALID);
548#else
549 irq_set_noprobe(virq);
550#endif
551 return 0;
552}
553
554static struct irq_domain_ops pm860x_irq_domain_ops = {
555 .map = pm860x_irq_domain_map,
556 .xlate = irq_domain_xlate_onetwocell,
557};
558
542static int __devinit device_gpadc_init(struct pm860x_chip *chip, 559static int __devinit device_gpadc_init(struct pm860x_chip *chip,
543 struct pm860x_platform_data *pdata) 560 struct pm860x_platform_data *pdata)
544{ 561{
@@ -593,13 +610,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
593 : chip->companion; 610 : chip->companion;
594 unsigned char status_buf[INT_STATUS_NUM]; 611 unsigned char status_buf[INT_STATUS_NUM];
595 unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; 612 unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
596 int i, data, mask, ret = -EINVAL; 613 int data, mask, ret = -EINVAL;
597 int __irq; 614 int nr_irqs, irq_base = -1;
598 615 struct device_node *node = i2c->dev.of_node;
599 if (!pdata || !pdata->irq_base) {
600 dev_warn(chip->dev, "No interrupt support on IRQ base\n");
601 return -EINVAL;
602 }
603 616
604 mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR 617 mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
605 | PM8607_B0_MISC1_INT_MASK; 618 | PM8607_B0_MISC1_INT_MASK;
@@ -639,25 +652,23 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
639 goto out; 652 goto out;
640 653
641 mutex_init(&chip->irq_lock); 654 mutex_init(&chip->irq_lock);
642 chip->irq_base = pdata->irq_base; 655
656 if (pdata && pdata->irq_base)
657 irq_base = pdata->irq_base;
658 nr_irqs = ARRAY_SIZE(pm860x_irqs);
659 chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
660 if (chip->irq_base < 0) {
661 dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
662 chip->irq_base);
663 ret = -EBUSY;
664 goto out;
665 }
666 irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
667 &pm860x_irq_domain_ops, chip);
643 chip->core_irq = i2c->irq; 668 chip->core_irq = i2c->irq;
644 if (!chip->core_irq) 669 if (!chip->core_irq)
645 goto out; 670 goto out;
646 671
647 /* register IRQ by genirq */
648 for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
649 __irq = i + chip->irq_base;
650 irq_set_chip_data(__irq, chip);
651 irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
652 handle_edge_irq);
653 irq_set_nested_thread(__irq, 1);
654#ifdef CONFIG_ARM
655 set_irq_flags(__irq, IRQF_VALID);
656#else
657 irq_set_noprobe(__irq);
658#endif
659 }
660
661 ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT, 672 ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
662 "88pm860x", chip); 673 "88pm860x", chip);
663 if (ret) { 674 if (ret) {