aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-05 18:37:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-05 18:37:40 -0400
commitcbda94e039c3862326a65d1d0506447af8330c3c (patch)
tree1147da54ec6eb7e1081977f07e62d514b981d9a3 /drivers/irqchip/irq-gic.c
parentf83ccb93585d1f472c30fa2bbb8b56c23dbdb506 (diff)
parentf1d7d8c86bc8ca41c88acf10ce383c5104cf4920 (diff)
Merge tag 'drivers-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver changes from Arnd Bergmann: "These changes are mostly for ARM specific device drivers that either don't have an upstream maintainer, or that had the maintainer ask us to pick up the changes to avoid conflicts. A large chunk of this are clock drivers (bcm281xx, exynos, versatile, shmobile), aside from that, reset controllers for STi as well as a large rework of the Marvell Orion/EBU watchdog driver are notable" * tag 'drivers-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (99 commits) Revert "dts: socfpga: Add DTS entry for adding the stmmac glue layer for stmmac." Revert "net: stmmac: Add SOCFPGA glue driver" ARM: shmobile: r8a7791: Fix SCIFA3-5 clocks ARM: STi: Add reset controller support to mach-sti Kconfig drivers: reset: stih416: add softreset controller drivers: reset: stih415: add softreset controller drivers: reset: Reset controller driver for STiH416 drivers: reset: Reset controller driver for STiH415 drivers: reset: STi SoC system configuration reset controller support dts: socfpga: Add sysmgr node so the gmac can use to reference dts: socfpga: Add support for SD/MMC on the SOCFPGA platform reset: Add optional resets and stubs ARM: shmobile: r7s72100: fix bus clock calculation Power: Reset: Generalize qnap-poweroff to work on Synology devices. dts: socfpga: Update clock entry to support multiple parents ARM: socfpga: Update socfpga_defconfig dts: socfpga: Add DTS entry for adding the stmmac glue layer for stmmac. net: stmmac: Add SOCFPGA glue driver watchdog: orion_wdt: Use %pa to print 'phys_addr_t' drivers: cci: Export CCI PMU revision ...
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r--drivers/irqchip/irq-gic.c82
1 files changed, 72 insertions, 10 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 63922b9ba6b7..4300b6606f5e 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -824,16 +824,25 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
824 irq_set_chip_and_handler(irq, &gic_chip, 824 irq_set_chip_and_handler(irq, &gic_chip,
825 handle_fasteoi_irq); 825 handle_fasteoi_irq);
826 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 826 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
827
828 gic_routable_irq_domain_ops->map(d, irq, hw);
827 } 829 }
828 irq_set_chip_data(irq, d->host_data); 830 irq_set_chip_data(irq, d->host_data);
829 return 0; 831 return 0;
830} 832}
831 833
834static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
835{
836 gic_routable_irq_domain_ops->unmap(d, irq);
837}
838
832static int gic_irq_domain_xlate(struct irq_domain *d, 839static int gic_irq_domain_xlate(struct irq_domain *d,
833 struct device_node *controller, 840 struct device_node *controller,
834 const u32 *intspec, unsigned int intsize, 841 const u32 *intspec, unsigned int intsize,
835 unsigned long *out_hwirq, unsigned int *out_type) 842 unsigned long *out_hwirq, unsigned int *out_type)
836{ 843{
844 unsigned long ret = 0;
845
837 if (d->of_node != controller) 846 if (d->of_node != controller)
838 return -EINVAL; 847 return -EINVAL;
839 if (intsize < 3) 848 if (intsize < 3)
@@ -843,11 +852,20 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
843 *out_hwirq = intspec[1] + 16; 852 *out_hwirq = intspec[1] + 16;
844 853
845 /* For SPIs, we need to add 16 more to get the GIC irq ID number */ 854 /* For SPIs, we need to add 16 more to get the GIC irq ID number */
846 if (!intspec[0]) 855 if (!intspec[0]) {
847 *out_hwirq += 16; 856 ret = gic_routable_irq_domain_ops->xlate(d, controller,
857 intspec,
858 intsize,
859 out_hwirq,
860 out_type);
861
862 if (IS_ERR_VALUE(ret))
863 return ret;
864 }
848 865
849 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 866 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
850 return 0; 867
868 return ret;
851} 869}
852 870
853#ifdef CONFIG_SMP 871#ifdef CONFIG_SMP
@@ -871,9 +889,41 @@ static struct notifier_block gic_cpu_notifier = {
871 889
872static const struct irq_domain_ops gic_irq_domain_ops = { 890static const struct irq_domain_ops gic_irq_domain_ops = {
873 .map = gic_irq_domain_map, 891 .map = gic_irq_domain_map,
892 .unmap = gic_irq_domain_unmap,
874 .xlate = gic_irq_domain_xlate, 893 .xlate = gic_irq_domain_xlate,
875}; 894};
876 895
896/* Default functions for routable irq domain */
897static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq,
898 irq_hw_number_t hw)
899{
900 return 0;
901}
902
903static void gic_routable_irq_domain_unmap(struct irq_domain *d,
904 unsigned int irq)
905{
906}
907
908static int gic_routable_irq_domain_xlate(struct irq_domain *d,
909 struct device_node *controller,
910 const u32 *intspec, unsigned int intsize,
911 unsigned long *out_hwirq,
912 unsigned int *out_type)
913{
914 *out_hwirq += 16;
915 return 0;
916}
917
918const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
919 .map = gic_routable_irq_domain_map,
920 .unmap = gic_routable_irq_domain_unmap,
921 .xlate = gic_routable_irq_domain_xlate,
922};
923
924const struct irq_domain_ops *gic_routable_irq_domain_ops =
925 &gic_default_routable_irq_domain_ops;
926
877void __init gic_init_bases(unsigned int gic_nr, int irq_start, 927void __init gic_init_bases(unsigned int gic_nr, int irq_start,
878 void __iomem *dist_base, void __iomem *cpu_base, 928 void __iomem *dist_base, void __iomem *cpu_base,
879 u32 percpu_offset, struct device_node *node) 929 u32 percpu_offset, struct device_node *node)
@@ -881,6 +931,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
881 irq_hw_number_t hwirq_base; 931 irq_hw_number_t hwirq_base;
882 struct gic_chip_data *gic; 932 struct gic_chip_data *gic;
883 int gic_irqs, irq_base, i; 933 int gic_irqs, irq_base, i;
934 int nr_routable_irqs;
884 935
885 BUG_ON(gic_nr >= MAX_GIC_NR); 936 BUG_ON(gic_nr >= MAX_GIC_NR);
886 937
@@ -946,14 +997,25 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
946 gic->gic_irqs = gic_irqs; 997 gic->gic_irqs = gic_irqs;
947 998
948 gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ 999 gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
949 irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id()); 1000
950 if (IS_ERR_VALUE(irq_base)) { 1001 if (of_property_read_u32(node, "arm,routable-irqs",
951 WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", 1002 &nr_routable_irqs)) {
952 irq_start); 1003 irq_base = irq_alloc_descs(irq_start, 16, gic_irqs,
953 irq_base = irq_start; 1004 numa_node_id());
1005 if (IS_ERR_VALUE(irq_base)) {
1006 WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
1007 irq_start);
1008 irq_base = irq_start;
1009 }
1010
1011 gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
1012 hwirq_base, &gic_irq_domain_ops, gic);
1013 } else {
1014 gic->domain = irq_domain_add_linear(node, nr_routable_irqs,
1015 &gic_irq_domain_ops,
1016 gic);
954 } 1017 }
955 gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, 1018
956 hwirq_base, &gic_irq_domain_ops, gic);
957 if (WARN_ON(!gic->domain)) 1019 if (WARN_ON(!gic->domain))
958 return; 1020 return;
959 1021