Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: 88pm860x: Use irqdomain

Use irqdomain and allocating interrupts. It's necessary for supporting
DT mode.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Haojian Zhuang and committed by
Samuel Ortiz
837c8293 8284328c

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