diff options
author | Qing Xu <qingx@marvell.com> | 2013-02-04 23:40:42 +0800 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-02-14 00:23:00 +0100 |
commit | 4e405ae256b7e04f7c1213136f3bfd9fb76e2023 (patch) | |
tree | f821f9b999202d623c50eafcb9db5431937f1f46 /drivers/mfd/max8925-core.c | |
parent | dcd560c8587171bb22c75c41ac2a70986bbbde7f (diff) | |
download | linux-stable-4e405ae256b7e04f7c1213136f3bfd9fb76e2023.tar.gz linux-stable-4e405ae256b7e04f7c1213136f3bfd9fb76e2023.tar.bz2 linux-stable-4e405ae256b7e04f7c1213136f3bfd9fb76e2023.zip |
mfd: max8925: Add irqdomain for dt
Add irqdomains for max8925's main irq, wrap irq register operations
into irqdomain's map func. it is necessary for dt support.
Also, add dt support for max8925 driver.
Signed-off-by: Qing Xu <qingx@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/max8925-core.c')
-rw-r--r-- | drivers/mfd/max8925-core.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index e32466e865b9..0ad8d9a7c15a 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -14,10 +14,13 @@ #include <linux/i2c.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/irqdomain.h> #include <linux/platform_device.h> #include <linux/regulator/machine.h> #include <linux/mfd/core.h> #include <linux/mfd/max8925.h> +#include <linux/of.h> +#include <linux/of_platform.h> static struct resource bk_resources[] = { { 0x84, 0x84, "mode control", IORESOURCE_REG, }, @@ -639,17 +642,33 @@ static struct irq_chip max8925_irq_chip = { .irq_disable = max8925_irq_disable, }; +static int max8925_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + irq_set_chip_data(virq, d->host_data); + irq_set_chip_and_handler(virq, &max8925_irq_chip, handle_edge_irq); + irq_set_nested_thread(virq, 1); +#ifdef CONFIG_ARM + set_irq_flags(virq, IRQF_VALID); +#else + irq_set_noprobe(virq); +#endif + return 0; +} + +static struct irq_domain_ops max8925_irq_domain_ops = { + .map = max8925_irq_domain_map, + .xlate = irq_domain_xlate_onetwocell, +}; + + static int max8925_irq_init(struct max8925_chip *chip, int irq, struct max8925_platform_data *pdata) { unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; - int i, ret; - int __irq; + int ret; + struct device_node *node = chip->dev->of_node; - if (!pdata || !pdata->irq_base) { - dev_warn(chip->dev, "No interrupt support on IRQ base\n"); - return -EINVAL; - } /* clear all interrupts */ max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); @@ -667,35 +686,30 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); mutex_init(&chip->irq_lock); - chip->core_irq = irq; - chip->irq_base = pdata->irq_base; - - /* register with genirq */ - for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { - __irq = i + chip->irq_base; - irq_set_chip_data(__irq, chip); - irq_set_chip_and_handler(__irq, &max8925_irq_chip, - handle_edge_irq); - irq_set_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#else - irq_set_noprobe(__irq); -#endif - } - if (!irq) { - dev_warn(chip->dev, "No interrupt support on core IRQ\n"); - goto tsc_irq; + chip->irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_IRQS, 0); + if (chip->irq_base < 0) { + dev_err(chip->dev, "Failed to allocate interrupts, ret:%d\n", + chip->irq_base); + return -EBUSY; } + irq_domain_add_legacy(node, MAX8925_NR_IRQS, chip->irq_base, 0, + &max8925_irq_domain_ops, chip); + + /* request irq handler for pmic main irq*/ + chip->core_irq = irq; + if (!chip->core_irq) + return -EBUSY; ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT, "max8925", chip); if (ret) { dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); chip->core_irq = 0; + return -EBUSY; } -tsc_irq: + /* request irq handler for pmic tsc irq*/ + /* mask TSC interrupt */ max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); @@ -704,7 +718,6 @@ tsc_irq: return 0; } chip->tsc_irq = pdata->tsc_irq; - ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, flags | IRQF_ONESHOT, "max8925-tsc", chip); if (ret) { @@ -875,11 +888,11 @@ int max8925_device_init(struct max8925_chip *chip, if (pdata && pdata->power) { ret = mfd_add_devices(chip->dev, 0, &power_devs[0], - ARRAY_SIZE(power_devs), + ARRAY_SIZE(power_devs), &power_supply_resources[0], 0, NULL); if (ret < 0) { - dev_err(chip->dev, "Failed to add power supply " - "subdev\n"); + dev_err(chip->dev, + "Failed to add power supply subdev\n"); goto out_dev; } } |