diff options
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
-rw-r--r-- | arch/mips/cavium-octeon/octeon-irq.c | 399 |
1 files changed, 314 insertions, 85 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index ffd4ae660f79..7fb1f222b8a5 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c | |||
@@ -3,14 +3,17 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks | 6 | * Copyright (C) 2004-2012 Cavium, Inc. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
10 | #include <linux/irqdomain.h> | ||
10 | #include <linux/bitops.h> | 11 | #include <linux/bitops.h> |
11 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
13 | #include <linux/slab.h> | ||
12 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
13 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/of.h> | ||
14 | 17 | ||
15 | #include <asm/octeon/octeon.h> | 18 | #include <asm/octeon/octeon.h> |
16 | 19 | ||
@@ -42,9 +45,9 @@ struct octeon_core_chip_data { | |||
42 | 45 | ||
43 | static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES]; | 46 | static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES]; |
44 | 47 | ||
45 | static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit, | 48 | static void octeon_irq_set_ciu_mapping(int irq, int line, int bit, |
46 | struct irq_chip *chip, | 49 | struct irq_chip *chip, |
47 | irq_flow_handler_t handler) | 50 | irq_flow_handler_t handler) |
48 | { | 51 | { |
49 | union octeon_ciu_chip_data cd; | 52 | union octeon_ciu_chip_data cd; |
50 | 53 | ||
@@ -505,6 +508,85 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data) | |||
505 | } | 508 | } |
506 | } | 509 | } |
507 | 510 | ||
511 | static void octeon_irq_gpio_setup(struct irq_data *data) | ||
512 | { | ||
513 | union cvmx_gpio_bit_cfgx cfg; | ||
514 | union octeon_ciu_chip_data cd; | ||
515 | u32 t = irqd_get_trigger_type(data); | ||
516 | |||
517 | cd.p = irq_data_get_irq_chip_data(data); | ||
518 | |||
519 | cfg.u64 = 0; | ||
520 | cfg.s.int_en = 1; | ||
521 | cfg.s.int_type = (t & IRQ_TYPE_EDGE_BOTH) != 0; | ||
522 | cfg.s.rx_xor = (t & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) != 0; | ||
523 | |||
524 | /* 140 nS glitch filter*/ | ||
525 | cfg.s.fil_cnt = 7; | ||
526 | cfg.s.fil_sel = 3; | ||
527 | |||
528 | cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), cfg.u64); | ||
529 | } | ||
530 | |||
531 | static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data) | ||
532 | { | ||
533 | octeon_irq_gpio_setup(data); | ||
534 | octeon_irq_ciu_enable_v2(data); | ||
535 | } | ||
536 | |||
537 | static void octeon_irq_ciu_enable_gpio(struct irq_data *data) | ||
538 | { | ||
539 | octeon_irq_gpio_setup(data); | ||
540 | octeon_irq_ciu_enable(data); | ||
541 | } | ||
542 | |||
543 | static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t) | ||
544 | { | ||
545 | irqd_set_trigger_type(data, t); | ||
546 | octeon_irq_gpio_setup(data); | ||
547 | |||
548 | return IRQ_SET_MASK_OK; | ||
549 | } | ||
550 | |||
551 | static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data) | ||
552 | { | ||
553 | union octeon_ciu_chip_data cd; | ||
554 | |||
555 | cd.p = irq_data_get_irq_chip_data(data); | ||
556 | cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0); | ||
557 | |||
558 | octeon_irq_ciu_disable_all_v2(data); | ||
559 | } | ||
560 | |||
561 | static void octeon_irq_ciu_disable_gpio(struct irq_data *data) | ||
562 | { | ||
563 | union octeon_ciu_chip_data cd; | ||
564 | |||
565 | cd.p = irq_data_get_irq_chip_data(data); | ||
566 | cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0); | ||
567 | |||
568 | octeon_irq_ciu_disable_all(data); | ||
569 | } | ||
570 | |||
571 | static void octeon_irq_ciu_gpio_ack(struct irq_data *data) | ||
572 | { | ||
573 | union octeon_ciu_chip_data cd; | ||
574 | u64 mask; | ||
575 | |||
576 | cd.p = irq_data_get_irq_chip_data(data); | ||
577 | mask = 1ull << (cd.s.bit - 16); | ||
578 | |||
579 | cvmx_write_csr(CVMX_GPIO_INT_CLR, mask); | ||
580 | } | ||
581 | |||
582 | static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc) | ||
583 | { | ||
584 | if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH) | ||
585 | handle_edge_irq(irq, desc); | ||
586 | else | ||
587 | handle_level_irq(irq, desc); | ||
588 | } | ||
589 | |||
508 | #ifdef CONFIG_SMP | 590 | #ifdef CONFIG_SMP |
509 | 591 | ||
510 | static void octeon_irq_cpu_offline_ciu(struct irq_data *data) | 592 | static void octeon_irq_cpu_offline_ciu(struct irq_data *data) |
@@ -650,18 +732,6 @@ static struct irq_chip octeon_irq_chip_ciu_v2 = { | |||
650 | .name = "CIU", | 732 | .name = "CIU", |
651 | .irq_enable = octeon_irq_ciu_enable_v2, | 733 | .irq_enable = octeon_irq_ciu_enable_v2, |
652 | .irq_disable = octeon_irq_ciu_disable_all_v2, | 734 | .irq_disable = octeon_irq_ciu_disable_all_v2, |
653 | .irq_mask = octeon_irq_ciu_disable_local_v2, | ||
654 | .irq_unmask = octeon_irq_ciu_enable_v2, | ||
655 | #ifdef CONFIG_SMP | ||
656 | .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, | ||
657 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | ||
658 | #endif | ||
659 | }; | ||
660 | |||
661 | static struct irq_chip octeon_irq_chip_ciu_edge_v2 = { | ||
662 | .name = "CIU-E", | ||
663 | .irq_enable = octeon_irq_ciu_enable_v2, | ||
664 | .irq_disable = octeon_irq_ciu_disable_all_v2, | ||
665 | .irq_ack = octeon_irq_ciu_ack, | 735 | .irq_ack = octeon_irq_ciu_ack, |
666 | .irq_mask = octeon_irq_ciu_disable_local_v2, | 736 | .irq_mask = octeon_irq_ciu_disable_local_v2, |
667 | .irq_unmask = octeon_irq_ciu_enable_v2, | 737 | .irq_unmask = octeon_irq_ciu_enable_v2, |
@@ -675,19 +745,8 @@ static struct irq_chip octeon_irq_chip_ciu = { | |||
675 | .name = "CIU", | 745 | .name = "CIU", |
676 | .irq_enable = octeon_irq_ciu_enable, | 746 | .irq_enable = octeon_irq_ciu_enable, |
677 | .irq_disable = octeon_irq_ciu_disable_all, | 747 | .irq_disable = octeon_irq_ciu_disable_all, |
678 | .irq_mask = octeon_irq_dummy_mask, | ||
679 | #ifdef CONFIG_SMP | ||
680 | .irq_set_affinity = octeon_irq_ciu_set_affinity, | ||
681 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | ||
682 | #endif | ||
683 | }; | ||
684 | |||
685 | static struct irq_chip octeon_irq_chip_ciu_edge = { | ||
686 | .name = "CIU-E", | ||
687 | .irq_enable = octeon_irq_ciu_enable, | ||
688 | .irq_disable = octeon_irq_ciu_disable_all, | ||
689 | .irq_mask = octeon_irq_dummy_mask, | ||
690 | .irq_ack = octeon_irq_ciu_ack, | 748 | .irq_ack = octeon_irq_ciu_ack, |
749 | .irq_mask = octeon_irq_dummy_mask, | ||
691 | #ifdef CONFIG_SMP | 750 | #ifdef CONFIG_SMP |
692 | .irq_set_affinity = octeon_irq_ciu_set_affinity, | 751 | .irq_set_affinity = octeon_irq_ciu_set_affinity, |
693 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | 752 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, |
@@ -717,6 +776,33 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = { | |||
717 | .flags = IRQCHIP_ONOFFLINE_ENABLED, | 776 | .flags = IRQCHIP_ONOFFLINE_ENABLED, |
718 | }; | 777 | }; |
719 | 778 | ||
779 | static struct irq_chip octeon_irq_chip_ciu_gpio_v2 = { | ||
780 | .name = "CIU-GPIO", | ||
781 | .irq_enable = octeon_irq_ciu_enable_gpio_v2, | ||
782 | .irq_disable = octeon_irq_ciu_disable_gpio_v2, | ||
783 | .irq_ack = octeon_irq_ciu_gpio_ack, | ||
784 | .irq_mask = octeon_irq_ciu_disable_local_v2, | ||
785 | .irq_unmask = octeon_irq_ciu_enable_v2, | ||
786 | .irq_set_type = octeon_irq_ciu_gpio_set_type, | ||
787 | #ifdef CONFIG_SMP | ||
788 | .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, | ||
789 | #endif | ||
790 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
791 | }; | ||
792 | |||
793 | static struct irq_chip octeon_irq_chip_ciu_gpio = { | ||
794 | .name = "CIU-GPIO", | ||
795 | .irq_enable = octeon_irq_ciu_enable_gpio, | ||
796 | .irq_disable = octeon_irq_ciu_disable_gpio, | ||
797 | .irq_mask = octeon_irq_dummy_mask, | ||
798 | .irq_ack = octeon_irq_ciu_gpio_ack, | ||
799 | .irq_set_type = octeon_irq_ciu_gpio_set_type, | ||
800 | #ifdef CONFIG_SMP | ||
801 | .irq_set_affinity = octeon_irq_ciu_set_affinity, | ||
802 | #endif | ||
803 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
804 | }; | ||
805 | |||
720 | /* | 806 | /* |
721 | * Watchdog interrupts are special. They are associated with a single | 807 | * Watchdog interrupts are special. They are associated with a single |
722 | * core, so we hardwire the affinity to that core. | 808 | * core, so we hardwire the affinity to that core. |
@@ -764,6 +850,178 @@ static struct irq_chip octeon_irq_chip_ciu_wd = { | |||
764 | .irq_mask = octeon_irq_dummy_mask, | 850 | .irq_mask = octeon_irq_dummy_mask, |
765 | }; | 851 | }; |
766 | 852 | ||
853 | static bool octeon_irq_ciu_is_edge(unsigned int line, unsigned int bit) | ||
854 | { | ||
855 | bool edge = false; | ||
856 | |||
857 | if (line == 0) | ||
858 | switch (bit) { | ||
859 | case 48 ... 49: /* GMX DRP */ | ||
860 | case 50: /* IPD_DRP */ | ||
861 | case 52 ... 55: /* Timers */ | ||
862 | case 58: /* MPI */ | ||
863 | edge = true; | ||
864 | break; | ||
865 | default: | ||
866 | break; | ||
867 | } | ||
868 | else /* line == 1 */ | ||
869 | switch (bit) { | ||
870 | case 47: /* PTP */ | ||
871 | edge = true; | ||
872 | break; | ||
873 | default: | ||
874 | break; | ||
875 | } | ||
876 | return edge; | ||
877 | } | ||
878 | |||
879 | struct octeon_irq_gpio_domain_data { | ||
880 | unsigned int base_hwirq; | ||
881 | }; | ||
882 | |||
883 | static int octeon_irq_gpio_xlat(struct irq_domain *d, | ||
884 | struct device_node *node, | ||
885 | const u32 *intspec, | ||
886 | unsigned int intsize, | ||
887 | unsigned long *out_hwirq, | ||
888 | unsigned int *out_type) | ||
889 | { | ||
890 | unsigned int type; | ||
891 | unsigned int pin; | ||
892 | unsigned int trigger; | ||
893 | struct octeon_irq_gpio_domain_data *gpiod; | ||
894 | |||
895 | if (d->of_node != node) | ||
896 | return -EINVAL; | ||
897 | |||
898 | if (intsize < 2) | ||
899 | return -EINVAL; | ||
900 | |||
901 | pin = intspec[0]; | ||
902 | if (pin >= 16) | ||
903 | return -EINVAL; | ||
904 | |||
905 | trigger = intspec[1]; | ||
906 | |||
907 | switch (trigger) { | ||
908 | case 1: | ||
909 | type = IRQ_TYPE_EDGE_RISING; | ||
910 | break; | ||
911 | case 2: | ||
912 | type = IRQ_TYPE_EDGE_FALLING; | ||
913 | break; | ||
914 | case 4: | ||
915 | type = IRQ_TYPE_LEVEL_HIGH; | ||
916 | break; | ||
917 | case 8: | ||
918 | type = IRQ_TYPE_LEVEL_LOW; | ||
919 | break; | ||
920 | default: | ||
921 | pr_err("Error: (%s) Invalid irq trigger specification: %x\n", | ||
922 | node->name, | ||
923 | trigger); | ||
924 | type = IRQ_TYPE_LEVEL_LOW; | ||
925 | break; | ||
926 | } | ||
927 | *out_type = type; | ||
928 | gpiod = d->host_data; | ||
929 | *out_hwirq = gpiod->base_hwirq + pin; | ||
930 | |||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | static int octeon_irq_ciu_xlat(struct irq_domain *d, | ||
935 | struct device_node *node, | ||
936 | const u32 *intspec, | ||
937 | unsigned int intsize, | ||
938 | unsigned long *out_hwirq, | ||
939 | unsigned int *out_type) | ||
940 | { | ||
941 | unsigned int ciu, bit; | ||
942 | |||
943 | ciu = intspec[0]; | ||
944 | bit = intspec[1]; | ||
945 | |||
946 | if (ciu > 1 || bit > 63) | ||
947 | return -EINVAL; | ||
948 | |||
949 | /* These are the GPIO lines */ | ||
950 | if (ciu == 0 && bit >= 16 && bit < 32) | ||
951 | return -EINVAL; | ||
952 | |||
953 | *out_hwirq = (ciu << 6) | bit; | ||
954 | *out_type = 0; | ||
955 | |||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | static struct irq_chip *octeon_irq_ciu_chip; | ||
960 | static struct irq_chip *octeon_irq_gpio_chip; | ||
961 | |||
962 | static bool octeon_irq_virq_in_range(unsigned int virq) | ||
963 | { | ||
964 | /* We cannot let it overflow the mapping array. */ | ||
965 | if (virq < (1ul << 8 * sizeof(octeon_irq_ciu_to_irq[0][0]))) | ||
966 | return true; | ||
967 | |||
968 | WARN_ONCE(true, "virq out of range %u.\n", virq); | ||
969 | return false; | ||
970 | } | ||
971 | |||
972 | static int octeon_irq_ciu_map(struct irq_domain *d, | ||
973 | unsigned int virq, irq_hw_number_t hw) | ||
974 | { | ||
975 | unsigned int line = hw >> 6; | ||
976 | unsigned int bit = hw & 63; | ||
977 | |||
978 | if (!octeon_irq_virq_in_range(virq)) | ||
979 | return -EINVAL; | ||
980 | |||
981 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) | ||
982 | return -EINVAL; | ||
983 | |||
984 | if (octeon_irq_ciu_is_edge(line, bit)) | ||
985 | octeon_irq_set_ciu_mapping(virq, line, bit, | ||
986 | octeon_irq_ciu_chip, | ||
987 | handle_edge_irq); | ||
988 | else | ||
989 | octeon_irq_set_ciu_mapping(virq, line, bit, | ||
990 | octeon_irq_ciu_chip, | ||
991 | handle_level_irq); | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | static int octeon_irq_gpio_map(struct irq_domain *d, | ||
997 | unsigned int virq, irq_hw_number_t hw) | ||
998 | { | ||
999 | unsigned int line = hw >> 6; | ||
1000 | unsigned int bit = hw & 63; | ||
1001 | |||
1002 | if (!octeon_irq_virq_in_range(virq)) | ||
1003 | return -EINVAL; | ||
1004 | |||
1005 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) | ||
1006 | return -EINVAL; | ||
1007 | |||
1008 | octeon_irq_set_ciu_mapping(virq, line, bit, | ||
1009 | octeon_irq_gpio_chip, | ||
1010 | octeon_irq_handle_gpio); | ||
1011 | |||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static struct irq_domain_ops octeon_irq_domain_ciu_ops = { | ||
1016 | .map = octeon_irq_ciu_map, | ||
1017 | .xlate = octeon_irq_ciu_xlat, | ||
1018 | }; | ||
1019 | |||
1020 | static struct irq_domain_ops octeon_irq_domain_gpio_ops = { | ||
1021 | .map = octeon_irq_gpio_map, | ||
1022 | .xlate = octeon_irq_gpio_xlat, | ||
1023 | }; | ||
1024 | |||
767 | static void octeon_irq_ip2_v1(void) | 1025 | static void octeon_irq_ip2_v1(void) |
768 | { | 1026 | { |
769 | const unsigned long core_id = cvmx_get_core_num(); | 1027 | const unsigned long core_id = cvmx_get_core_num(); |
@@ -887,9 +1145,10 @@ static void __init octeon_irq_init_ciu(void) | |||
887 | { | 1145 | { |
888 | unsigned int i; | 1146 | unsigned int i; |
889 | struct irq_chip *chip; | 1147 | struct irq_chip *chip; |
890 | struct irq_chip *chip_edge; | ||
891 | struct irq_chip *chip_mbox; | 1148 | struct irq_chip *chip_mbox; |
892 | struct irq_chip *chip_wd; | 1149 | struct irq_chip *chip_wd; |
1150 | struct device_node *gpio_node; | ||
1151 | struct device_node *ciu_node; | ||
893 | 1152 | ||
894 | octeon_irq_init_ciu_percpu(); | 1153 | octeon_irq_init_ciu_percpu(); |
895 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; | 1154 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; |
@@ -901,17 +1160,18 @@ static void __init octeon_irq_init_ciu(void) | |||
901 | octeon_irq_ip2 = octeon_irq_ip2_v2; | 1160 | octeon_irq_ip2 = octeon_irq_ip2_v2; |
902 | octeon_irq_ip3 = octeon_irq_ip3_v2; | 1161 | octeon_irq_ip3 = octeon_irq_ip3_v2; |
903 | chip = &octeon_irq_chip_ciu_v2; | 1162 | chip = &octeon_irq_chip_ciu_v2; |
904 | chip_edge = &octeon_irq_chip_ciu_edge_v2; | ||
905 | chip_mbox = &octeon_irq_chip_ciu_mbox_v2; | 1163 | chip_mbox = &octeon_irq_chip_ciu_mbox_v2; |
906 | chip_wd = &octeon_irq_chip_ciu_wd_v2; | 1164 | chip_wd = &octeon_irq_chip_ciu_wd_v2; |
1165 | octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio_v2; | ||
907 | } else { | 1166 | } else { |
908 | octeon_irq_ip2 = octeon_irq_ip2_v1; | 1167 | octeon_irq_ip2 = octeon_irq_ip2_v1; |
909 | octeon_irq_ip3 = octeon_irq_ip3_v1; | 1168 | octeon_irq_ip3 = octeon_irq_ip3_v1; |
910 | chip = &octeon_irq_chip_ciu; | 1169 | chip = &octeon_irq_chip_ciu; |
911 | chip_edge = &octeon_irq_chip_ciu_edge; | ||
912 | chip_mbox = &octeon_irq_chip_ciu_mbox; | 1170 | chip_mbox = &octeon_irq_chip_ciu_mbox; |
913 | chip_wd = &octeon_irq_chip_ciu_wd; | 1171 | chip_wd = &octeon_irq_chip_ciu_wd; |
1172 | octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio; | ||
914 | } | 1173 | } |
1174 | octeon_irq_ciu_chip = chip; | ||
915 | octeon_irq_ip4 = octeon_irq_ip4_mask; | 1175 | octeon_irq_ip4 = octeon_irq_ip4_mask; |
916 | 1176 | ||
917 | /* Mips internal */ | 1177 | /* Mips internal */ |
@@ -920,80 +1180,49 @@ static void __init octeon_irq_init_ciu(void) | |||
920 | /* CIU_0 */ | 1180 | /* CIU_0 */ |
921 | for (i = 0; i < 16; i++) | 1181 | for (i = 0; i < 16; i++) |
922 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); | 1182 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); |
923 | for (i = 0; i < 16; i++) | ||
924 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq); | ||
925 | 1183 | ||
926 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); | 1184 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); |
927 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); | 1185 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); |
928 | 1186 | ||
929 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq); | ||
930 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq); | ||
931 | |||
932 | for (i = 0; i < 4; i++) | 1187 | for (i = 0; i < 4; i++) |
933 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); | 1188 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); |
934 | for (i = 0; i < 4; i++) | 1189 | for (i = 0; i < 4; i++) |
935 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); | 1190 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); |
936 | 1191 | ||
937 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq); | ||
938 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); | 1192 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); |
939 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq); | ||
940 | |||
941 | for (i = 0; i < 2; i++) | ||
942 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq); | ||
943 | |||
944 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq); | ||
945 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq); | ||
946 | |||
947 | for (i = 0; i < 4; i++) | 1193 | for (i = 0; i < 4; i++) |
948 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq); | 1194 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq); |
949 | 1195 | ||
950 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); | 1196 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); |
951 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq); | ||
952 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq); | ||
953 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq); | ||
954 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq); | ||
955 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq); | ||
956 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq); | ||
957 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); | 1197 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); |
958 | 1198 | ||
959 | /* CIU_1 */ | 1199 | /* CIU_1 */ |
960 | for (i = 0; i < 16; i++) | 1200 | for (i = 0; i < 16; i++) |
961 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); | 1201 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); |
962 | 1202 | ||
963 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq); | ||
964 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); | 1203 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); |
965 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq); | 1204 | |
966 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq); | 1205 | gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio"); |
967 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq); | 1206 | if (gpio_node) { |
968 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq); | 1207 | struct octeon_irq_gpio_domain_data *gpiod; |
969 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq); | 1208 | |
970 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq); | 1209 | gpiod = kzalloc(sizeof(*gpiod), GFP_KERNEL); |
971 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq); | 1210 | if (gpiod) { |
972 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq); | 1211 | /* gpio domain host_data is the base hwirq number. */ |
973 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq); | 1212 | gpiod->base_hwirq = 16; |
974 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq); | 1213 | irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_gpio_ops, gpiod); |
975 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq); | 1214 | of_node_put(gpio_node); |
976 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq); | 1215 | } else |
977 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq); | 1216 | pr_warn("Cannot allocate memory for GPIO irq_domain.\n"); |
978 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq); | 1217 | } else |
979 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq); | 1218 | pr_warn("Cannot find device node for cavium,octeon-3860-gpio.\n"); |
980 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq); | 1219 | |
981 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq); | 1220 | ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu"); |
982 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq); | 1221 | if (ciu_node) { |
983 | 1222 | irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); | |
984 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq); | 1223 | of_node_put(ciu_node); |
985 | 1224 | } else | |
986 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq); | 1225 | pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n"); |
987 | |||
988 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq); | ||
989 | |||
990 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq); | ||
991 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq); | ||
992 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq); | ||
993 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq); | ||
994 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq); | ||
995 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq); | ||
996 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq); | ||
997 | 1226 | ||
998 | /* Enable the CIU lines */ | 1227 | /* Enable the CIU lines */ |
999 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); | 1228 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); |