twl4030-irq.c (5a903090e7aa561901b7f052eb744b480d6126d4) | twl4030-irq.c (ec1a07b3440cc28946a77a974c21570bbef6ffa1) |
---|---|
1/* 2 * twl4030-irq.c - TWL4030/TPS659x0 irq support 3 * 4 * Copyright (C) 2005-2006 Texas Instruments, Inc. 5 * 6 * Modifications to defer interrupt handling to a kernel thread: 7 * Copyright (C) 2006 MontaVista Software, Inc. 8 * --- 18 unchanged lines hidden (view full) --- 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 */ 29 30#include <linux/init.h> 31#include <linux/export.h> 32#include <linux/interrupt.h> 33#include <linux/irq.h> 34#include <linux/slab.h> | 1/* 2 * twl4030-irq.c - TWL4030/TPS659x0 irq support 3 * 4 * Copyright (C) 2005-2006 Texas Instruments, Inc. 5 * 6 * Modifications to defer interrupt handling to a kernel thread: 7 * Copyright (C) 2006 MontaVista Software, Inc. 8 * --- 18 unchanged lines hidden (view full) --- 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 */ 29 30#include <linux/init.h> 31#include <linux/export.h> 32#include <linux/interrupt.h> 33#include <linux/irq.h> 34#include <linux/slab.h> |
35 | |
36#include <linux/of.h> 37#include <linux/irqdomain.h> 38#include <linux/i2c/twl.h> 39 40#include "twl-core.h" 41 42/* 43 * TWL4030 IRQ handling has two stages in hardware, and thus in software. --- 590 unchanged lines hidden (view full) --- 634{ 635 int sih_mod; 636 const struct sih *sih = NULL; 637 struct sih_agent *agent; 638 int i, irq; 639 int status = -EINVAL; 640 641 /* only support modules with standard clear-on-read for now */ | 35#include <linux/of.h> 36#include <linux/irqdomain.h> 37#include <linux/i2c/twl.h> 38 39#include "twl-core.h" 40 41/* 42 * TWL4030 IRQ handling has two stages in hardware, and thus in software. --- 590 unchanged lines hidden (view full) --- 633{ 634 int sih_mod; 635 const struct sih *sih = NULL; 636 struct sih_agent *agent; 637 int i, irq; 638 int status = -EINVAL; 639 640 /* only support modules with standard clear-on-read for now */ |
642 for (sih_mod = 0, sih = sih_modules; 643 sih_mod < nr_sih_modules; | 641 for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules; |
644 sih_mod++, sih++) { 645 if (sih->module == module && sih->set_cor) { 646 status = 0; 647 break; 648 } 649 } | 642 sih_mod++, sih++) { 643 if (sih->module == module && sih->set_cor) { 644 status = 0; 645 break; 646 } 647 } |
648 |
|
650 if (status < 0) 651 return status; 652 653 agent = kzalloc(sizeof *agent, GFP_KERNEL); 654 if (!agent) 655 return -ENOMEM; 656 657 agent->irq_base = irq_base; --- 13 unchanged lines hidden (view full) --- 671 672 /* replace generic PIH handler (handle_simple_irq) */ 673 irq = sih_mod + twl4030_irq_base; 674 irq_set_handler_data(irq, agent); 675 agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); 676 status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, 677 agent->irq_name ?: sih->name, NULL); 678 | 649 if (status < 0) 650 return status; 651 652 agent = kzalloc(sizeof *agent, GFP_KERNEL); 653 if (!agent) 654 return -ENOMEM; 655 656 agent->irq_base = irq_base; --- 13 unchanged lines hidden (view full) --- 670 671 /* replace generic PIH handler (handle_simple_irq) */ 672 irq = sih_mod + twl4030_irq_base; 673 irq_set_handler_data(irq, agent); 674 agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); 675 status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, 676 agent->irq_name ?: sih->name, NULL); 677 |
679 pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, | 678 dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, |
680 irq, irq_base, irq_base + i - 1); 681 682 return status < 0 ? status : irq_base; 683} 684 685/* FIXME need a call to reverse twl4030_sih_setup() ... */ 686 687/*----------------------------------------------------------------------*/ 688 689/* FIXME pass in which interrupt line we'll use ... */ 690#define twl_irq_line 0 691 692int twl4030_init_irq(struct device *dev, int irq_num) 693{ 694 static struct irq_chip twl4030_irq_chip; | 679 irq, irq_base, irq_base + i - 1); 680 681 return status < 0 ? status : irq_base; 682} 683 684/* FIXME need a call to reverse twl4030_sih_setup() ... */ 685 686/*----------------------------------------------------------------------*/ 687 688/* FIXME pass in which interrupt line we'll use ... */ 689#define twl_irq_line 0 690 691int twl4030_init_irq(struct device *dev, int irq_num) 692{ 693 static struct irq_chip twl4030_irq_chip; |
694 int status, i; |
|
695 int irq_base, irq_end, nr_irqs; 696 struct device_node *node = dev->of_node; 697 | 695 int irq_base, irq_end, nr_irqs; 696 struct device_node *node = dev->of_node; 697 |
698 int status; 699 int i; 700 | |
701 /* 702 * TWL core and pwr interrupts must be contiguous because 703 * the hwirqs numbers are defined contiguously from 1 to 15. 704 * Create only one domain for both. 705 */ 706 nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS; 707 708 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); --- 13 unchanged lines hidden (view full) --- 722 */ 723 status = twl4030_init_sih_modules(twl_irq_line); 724 if (status < 0) 725 return status; 726 727 twl4030_irq_base = irq_base; 728 729 /* | 698 /* 699 * TWL core and pwr interrupts must be contiguous because 700 * the hwirqs numbers are defined contiguously from 1 to 15. 701 * Create only one domain for both. 702 */ 703 nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS; 704 705 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); --- 13 unchanged lines hidden (view full) --- 719 */ 720 status = twl4030_init_sih_modules(twl_irq_line); 721 if (status < 0) 722 return status; 723 724 twl4030_irq_base = irq_base; 725 726 /* |
730 * install an irq handler for each of the SIH modules; | 727 * Install an irq handler for each of the SIH modules; |
731 * clone dummy irq_chip since PIH can't *do* anything 732 */ 733 twl4030_irq_chip = dummy_irq_chip; 734 twl4030_irq_chip.name = "twl4030"; 735 736 twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; 737 738 for (i = irq_base; i < irq_end; i++) { 739 irq_set_chip_and_handler(i, &twl4030_irq_chip, 740 handle_simple_irq); 741 irq_set_nested_thread(i, 1); 742 activate_irq(i); 743 } 744 | 728 * clone dummy irq_chip since PIH can't *do* anything 729 */ 730 twl4030_irq_chip = dummy_irq_chip; 731 twl4030_irq_chip.name = "twl4030"; 732 733 twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; 734 735 for (i = irq_base; i < irq_end; i++) { 736 irq_set_chip_and_handler(i, &twl4030_irq_chip, 737 handle_simple_irq); 738 irq_set_nested_thread(i, 1); 739 activate_irq(i); 740 } 741 |
745 pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", | 742 dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH", |
746 irq_num, irq_base, irq_end); 747 748 /* ... and the PWR_INT module ... */ 749 status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end); 750 if (status < 0) { | 743 irq_num, irq_base, irq_end); 744 745 /* ... and the PWR_INT module ... */ 746 status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end); 747 if (status < 0) { |
751 pr_err("twl4030: sih_setup PWR INT --> %d\n", status); | 748 dev_err(dev, "sih_setup PWR INT --> %d\n", status); |
752 goto fail; 753 } 754 755 /* install an irq handler to demultiplex the TWL4030 interrupt */ 756 status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 757 IRQF_ONESHOT, 758 "TWL4030-PIH", NULL); 759 if (status < 0) { | 749 goto fail; 750 } 751 752 /* install an irq handler to demultiplex the TWL4030 interrupt */ 753 status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 754 IRQF_ONESHOT, 755 "TWL4030-PIH", NULL); 756 if (status < 0) { |
760 pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); | 757 dev_err(dev, "could not claim irq%d: %d\n", irq_num, status); |
761 goto fail_rqirq; 762 } 763 764 return irq_base; 765fail_rqirq: 766 /* clean up twl4030_sih_setup */ 767fail: 768 for (i = irq_base; i < irq_end; i++) { --- 29 unchanged lines hidden --- | 758 goto fail_rqirq; 759 } 760 761 return irq_base; 762fail_rqirq: 763 /* clean up twl4030_sih_setup */ 764fail: 765 for (i = irq_base; i < irq_end; i++) { --- 29 unchanged lines hidden --- |