aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/cavium-octeon/octeon-irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c111
1 files changed, 110 insertions, 1 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ffd4ae660f7..168b4891d7a 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -505,6 +505,85 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
505 } 505 }
506} 506}
507 507
508static void octeon_irq_gpio_setup(struct irq_data *data)
509{
510 union cvmx_gpio_bit_cfgx cfg;
511 union octeon_ciu_chip_data cd;
512 u32 t = irqd_get_trigger_type(data);
513
514 cd.p = irq_data_get_irq_chip_data(data);
515
516 cfg.u64 = 0;
517 cfg.s.int_en = 1;
518 cfg.s.int_type = (t & IRQ_TYPE_EDGE_BOTH) != 0;
519 cfg.s.rx_xor = (t & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) != 0;
520
521 /* 140 nS glitch filter*/
522 cfg.s.fil_cnt = 7;
523 cfg.s.fil_sel = 3;
524
525 cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), cfg.u64);
526}
527
528static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data)
529{
530 octeon_irq_gpio_setup(data);
531 octeon_irq_ciu_enable_v2(data);
532}
533
534static void octeon_irq_ciu_enable_gpio(struct irq_data *data)
535{
536 octeon_irq_gpio_setup(data);
537 octeon_irq_ciu_enable(data);
538}
539
540static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t)
541{
542 irqd_set_trigger_type(data, t);
543 octeon_irq_gpio_setup(data);
544
545 return IRQ_SET_MASK_OK;
546}
547
548static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data)
549{
550 union octeon_ciu_chip_data cd;
551
552 cd.p = irq_data_get_irq_chip_data(data);
553 cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
554
555 octeon_irq_ciu_disable_all_v2(data);
556}
557
558static void octeon_irq_ciu_disable_gpio(struct irq_data *data)
559{
560 union octeon_ciu_chip_data cd;
561
562 cd.p = irq_data_get_irq_chip_data(data);
563 cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
564
565 octeon_irq_ciu_disable_all(data);
566}
567
568static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
569{
570 union octeon_ciu_chip_data cd;
571 u64 mask;
572
573 cd.p = irq_data_get_irq_chip_data(data);
574 mask = 1ull << (cd.s.bit - 16);
575
576 cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
577}
578
579static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc)
580{
581 if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH)
582 handle_edge_irq(irq, desc);
583 else
584 handle_level_irq(irq, desc);
585}
586
508#ifdef CONFIG_SMP 587#ifdef CONFIG_SMP
509 588
510static void octeon_irq_cpu_offline_ciu(struct irq_data *data) 589static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
@@ -717,6 +796,33 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = {
717 .flags = IRQCHIP_ONOFFLINE_ENABLED, 796 .flags = IRQCHIP_ONOFFLINE_ENABLED,
718}; 797};
719 798
799static struct irq_chip octeon_irq_chip_ciu_gpio_v2 = {
800 .name = "CIU-GPIO",
801 .irq_enable = octeon_irq_ciu_enable_gpio_v2,
802 .irq_disable = octeon_irq_ciu_disable_gpio_v2,
803 .irq_ack = octeon_irq_ciu_gpio_ack,
804 .irq_mask = octeon_irq_ciu_disable_local_v2,
805 .irq_unmask = octeon_irq_ciu_enable_v2,
806 .irq_set_type = octeon_irq_ciu_gpio_set_type,
807#ifdef CONFIG_SMP
808 .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
809#endif
810 .flags = IRQCHIP_SET_TYPE_MASKED,
811};
812
813static struct irq_chip octeon_irq_chip_ciu_gpio = {
814 .name = "CIU-GPIO",
815 .irq_enable = octeon_irq_ciu_enable_gpio,
816 .irq_disable = octeon_irq_ciu_disable_gpio,
817 .irq_mask = octeon_irq_dummy_mask,
818 .irq_ack = octeon_irq_ciu_gpio_ack,
819 .irq_set_type = octeon_irq_ciu_gpio_set_type,
820#ifdef CONFIG_SMP
821 .irq_set_affinity = octeon_irq_ciu_set_affinity,
822#endif
823 .flags = IRQCHIP_SET_TYPE_MASKED,
824};
825
720/* 826/*
721 * Watchdog interrupts are special. They are associated with a single 827 * Watchdog interrupts are special. They are associated with a single
722 * core, so we hardwire the affinity to that core. 828 * core, so we hardwire the affinity to that core.
@@ -890,6 +996,7 @@ static void __init octeon_irq_init_ciu(void)
890 struct irq_chip *chip_edge; 996 struct irq_chip *chip_edge;
891 struct irq_chip *chip_mbox; 997 struct irq_chip *chip_mbox;
892 struct irq_chip *chip_wd; 998 struct irq_chip *chip_wd;
999 struct irq_chip *chip_gpio;
893 1000
894 octeon_irq_init_ciu_percpu(); 1001 octeon_irq_init_ciu_percpu();
895 octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; 1002 octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
@@ -904,6 +1011,7 @@ static void __init octeon_irq_init_ciu(void)
904 chip_edge = &octeon_irq_chip_ciu_edge_v2; 1011 chip_edge = &octeon_irq_chip_ciu_edge_v2;
905 chip_mbox = &octeon_irq_chip_ciu_mbox_v2; 1012 chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
906 chip_wd = &octeon_irq_chip_ciu_wd_v2; 1013 chip_wd = &octeon_irq_chip_ciu_wd_v2;
1014 chip_gpio = &octeon_irq_chip_ciu_gpio_v2;
907 } else { 1015 } else {
908 octeon_irq_ip2 = octeon_irq_ip2_v1; 1016 octeon_irq_ip2 = octeon_irq_ip2_v1;
909 octeon_irq_ip3 = octeon_irq_ip3_v1; 1017 octeon_irq_ip3 = octeon_irq_ip3_v1;
@@ -911,6 +1019,7 @@ static void __init octeon_irq_init_ciu(void)
911 chip_edge = &octeon_irq_chip_ciu_edge; 1019 chip_edge = &octeon_irq_chip_ciu_edge;
912 chip_mbox = &octeon_irq_chip_ciu_mbox; 1020 chip_mbox = &octeon_irq_chip_ciu_mbox;
913 chip_wd = &octeon_irq_chip_ciu_wd; 1021 chip_wd = &octeon_irq_chip_ciu_wd;
1022 chip_gpio = &octeon_irq_chip_ciu_gpio;
914 } 1023 }
915 octeon_irq_ip4 = octeon_irq_ip4_mask; 1024 octeon_irq_ip4 = octeon_irq_ip4_mask;
916 1025
@@ -921,7 +1030,7 @@ static void __init octeon_irq_init_ciu(void)
921 for (i = 0; i < 16; i++) 1030 for (i = 0; i < 16; i++)
922 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); 1031 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
923 for (i = 0; i < 16; i++) 1032 for (i = 0; i < 16; i++)
924 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq); 1033 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip_gpio, octeon_irq_handle_gpio);
925 1034
926 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); 1035 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); 1036 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);