diff options
Diffstat (limited to 'drivers/mfd/max8925-core.c')
-rw-r--r-- | drivers/mfd/max8925-core.c | 89 |
1 files changed, 50 insertions, 39 deletions
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index e32466e865b9..f0cc40296d8c 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -14,10 +14,13 @@ | |||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/irqdomain.h> | ||
17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
18 | #include <linux/regulator/machine.h> | 19 | #include <linux/regulator/machine.h> |
19 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/max8925.h> | 21 | #include <linux/mfd/max8925.h> |
22 | #include <linux/of.h> | ||
23 | #include <linux/of_platform.h> | ||
21 | 24 | ||
22 | static struct resource bk_resources[] = { | 25 | static struct resource bk_resources[] = { |
23 | { 0x84, 0x84, "mode control", IORESOURCE_REG, }, | 26 | { 0x84, 0x84, "mode control", IORESOURCE_REG, }, |
@@ -639,17 +642,33 @@ static struct irq_chip max8925_irq_chip = { | |||
639 | .irq_disable = max8925_irq_disable, | 642 | .irq_disable = max8925_irq_disable, |
640 | }; | 643 | }; |
641 | 644 | ||
645 | static int max8925_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
646 | irq_hw_number_t hw) | ||
647 | { | ||
648 | irq_set_chip_data(virq, d->host_data); | ||
649 | irq_set_chip_and_handler(virq, &max8925_irq_chip, handle_edge_irq); | ||
650 | irq_set_nested_thread(virq, 1); | ||
651 | #ifdef CONFIG_ARM | ||
652 | set_irq_flags(virq, IRQF_VALID); | ||
653 | #else | ||
654 | irq_set_noprobe(virq); | ||
655 | #endif | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static struct irq_domain_ops max8925_irq_domain_ops = { | ||
660 | .map = max8925_irq_domain_map, | ||
661 | .xlate = irq_domain_xlate_onetwocell, | ||
662 | }; | ||
663 | |||
664 | |||
642 | static int max8925_irq_init(struct max8925_chip *chip, int irq, | 665 | static int max8925_irq_init(struct max8925_chip *chip, int irq, |
643 | struct max8925_platform_data *pdata) | 666 | struct max8925_platform_data *pdata) |
644 | { | 667 | { |
645 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; | 668 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
646 | int i, ret; | 669 | int ret; |
647 | int __irq; | 670 | struct device_node *node = chip->dev->of_node; |
648 | 671 | ||
649 | if (!pdata || !pdata->irq_base) { | ||
650 | dev_warn(chip->dev, "No interrupt support on IRQ base\n"); | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | /* clear all interrupts */ | 672 | /* clear all interrupts */ |
654 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); | 673 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); |
655 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); | 674 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); |
@@ -667,35 +686,30 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, | |||
667 | max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); | 686 | max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); |
668 | 687 | ||
669 | mutex_init(&chip->irq_lock); | 688 | mutex_init(&chip->irq_lock); |
670 | chip->core_irq = irq; | 689 | chip->irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_IRQS, 0); |
671 | chip->irq_base = pdata->irq_base; | 690 | if (chip->irq_base < 0) { |
672 | 691 | dev_err(chip->dev, "Failed to allocate interrupts, ret:%d\n", | |
673 | /* register with genirq */ | 692 | chip->irq_base); |
674 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { | 693 | return -EBUSY; |
675 | __irq = i + chip->irq_base; | ||
676 | irq_set_chip_data(__irq, chip); | ||
677 | irq_set_chip_and_handler(__irq, &max8925_irq_chip, | ||
678 | handle_edge_irq); | ||
679 | irq_set_nested_thread(__irq, 1); | ||
680 | #ifdef CONFIG_ARM | ||
681 | set_irq_flags(__irq, IRQF_VALID); | ||
682 | #else | ||
683 | irq_set_noprobe(__irq); | ||
684 | #endif | ||
685 | } | ||
686 | if (!irq) { | ||
687 | dev_warn(chip->dev, "No interrupt support on core IRQ\n"); | ||
688 | goto tsc_irq; | ||
689 | } | 694 | } |
690 | 695 | ||
696 | irq_domain_add_legacy(node, MAX8925_NR_IRQS, chip->irq_base, 0, | ||
697 | &max8925_irq_domain_ops, chip); | ||
698 | |||
699 | /* request irq handler for pmic main irq*/ | ||
700 | chip->core_irq = irq; | ||
701 | if (!chip->core_irq) | ||
702 | return -EBUSY; | ||
691 | ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT, | 703 | ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT, |
692 | "max8925", chip); | 704 | "max8925", chip); |
693 | if (ret) { | 705 | if (ret) { |
694 | dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); | 706 | dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); |
695 | chip->core_irq = 0; | 707 | chip->core_irq = 0; |
708 | return -EBUSY; | ||
696 | } | 709 | } |
697 | 710 | ||
698 | tsc_irq: | 711 | /* request irq handler for pmic tsc irq*/ |
712 | |||
699 | /* mask TSC interrupt */ | 713 | /* mask TSC interrupt */ |
700 | max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); | 714 | max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); |
701 | 715 | ||
@@ -704,7 +718,6 @@ tsc_irq: | |||
704 | return 0; | 718 | return 0; |
705 | } | 719 | } |
706 | chip->tsc_irq = pdata->tsc_irq; | 720 | chip->tsc_irq = pdata->tsc_irq; |
707 | |||
708 | ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, | 721 | ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, |
709 | flags | IRQF_ONESHOT, "max8925-tsc", chip); | 722 | flags | IRQF_ONESHOT, "max8925-tsc", chip); |
710 | if (ret) { | 723 | if (ret) { |
@@ -846,7 +859,7 @@ int max8925_device_init(struct max8925_chip *chip, | |||
846 | 859 | ||
847 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 860 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
848 | ARRAY_SIZE(rtc_devs), | 861 | ARRAY_SIZE(rtc_devs), |
849 | &rtc_resources[0], chip->irq_base, NULL); | 862 | NULL, chip->irq_base, NULL); |
850 | if (ret < 0) { | 863 | if (ret < 0) { |
851 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 864 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
852 | goto out; | 865 | goto out; |
@@ -854,7 +867,7 @@ int max8925_device_init(struct max8925_chip *chip, | |||
854 | 867 | ||
855 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 868 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
856 | ARRAY_SIZE(onkey_devs), | 869 | ARRAY_SIZE(onkey_devs), |
857 | &onkey_resources[0], 0, NULL); | 870 | NULL, chip->irq_base, NULL); |
858 | if (ret < 0) { | 871 | if (ret < 0) { |
859 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 872 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
860 | goto out_dev; | 873 | goto out_dev; |
@@ -873,21 +886,19 @@ int max8925_device_init(struct max8925_chip *chip, | |||
873 | goto out_dev; | 886 | goto out_dev; |
874 | } | 887 | } |
875 | 888 | ||
876 | if (pdata && pdata->power) { | 889 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], |
877 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], | 890 | ARRAY_SIZE(power_devs), |
878 | ARRAY_SIZE(power_devs), | 891 | NULL, 0, NULL); |
879 | &power_supply_resources[0], 0, NULL); | 892 | if (ret < 0) { |
880 | if (ret < 0) { | 893 | dev_err(chip->dev, |
881 | dev_err(chip->dev, "Failed to add power supply " | 894 | "Failed to add power supply subdev, err = %d\n", ret); |
882 | "subdev\n"); | 895 | goto out_dev; |
883 | goto out_dev; | ||
884 | } | ||
885 | } | 896 | } |
886 | 897 | ||
887 | if (pdata && pdata->touch) { | 898 | if (pdata && pdata->touch) { |
888 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 899 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
889 | ARRAY_SIZE(touch_devs), | 900 | ARRAY_SIZE(touch_devs), |
890 | &touch_resources[0], 0, NULL); | 901 | NULL, chip->tsc_irq, NULL); |
891 | if (ret < 0) { | 902 | if (ret < 0) { |
892 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 903 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
893 | goto out_dev; | 904 | goto out_dev; |