diff options
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
| -rw-r--r-- | arch/mips/cavium-octeon/octeon-irq.c | 89 | 
1 files changed, 43 insertions, 46 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 7fb1f222b8a..274cd4fad30 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -61,6 +61,12 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,  	octeon_irq_ciu_to_irq[line][bit] = irq;  } +static void octeon_irq_force_ciu_mapping(struct irq_domain *domain, +					 int irq, int line, int bit) +{ +	irq_domain_associate(domain, irq, line << 6 | bit); +} +  static int octeon_coreid_for_cpu(int cpu)  {  #ifdef CONFIG_SMP @@ -183,19 +189,9 @@ static void __init octeon_irq_init_core(void)  		mutex_init(&cd->core_irq_mutex);  		irq = OCTEON_IRQ_SW0 + i; -		switch (irq) { -		case OCTEON_IRQ_TIMER: -		case OCTEON_IRQ_SW0: -		case OCTEON_IRQ_SW1: -		case OCTEON_IRQ_5: -		case OCTEON_IRQ_PERF: -			irq_set_chip_data(irq, cd); -			irq_set_chip_and_handler(irq, &octeon_irq_chip_core, -						 handle_percpu_irq); -			break; -		default: -			break; -		} +		irq_set_chip_data(irq, cd); +		irq_set_chip_and_handler(irq, &octeon_irq_chip_core, +					 handle_percpu_irq);  	}  } @@ -890,7 +886,6 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,  	unsigned int type;  	unsigned int pin;  	unsigned int trigger; -	struct octeon_irq_gpio_domain_data *gpiod;  	if (d->of_node != node)  		return -EINVAL; @@ -925,8 +920,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,  		break;  	}  	*out_type = type; -	gpiod = d->host_data; -	*out_hwirq = gpiod->base_hwirq + pin; +	*out_hwirq = pin;  	return 0;  } @@ -996,19 +990,21 @@ static int octeon_irq_ciu_map(struct irq_domain *d,  static int octeon_irq_gpio_map(struct irq_domain *d,  			       unsigned int virq, irq_hw_number_t hw)  { -	unsigned int line = hw >> 6; -	unsigned int bit = hw & 63; +	struct octeon_irq_gpio_domain_data *gpiod = d->host_data; +	unsigned int line, bit;  	if (!octeon_irq_virq_in_range(virq))  		return -EINVAL; +	hw += gpiod->base_hwirq; +	line = hw >> 6; +	bit = hw & 63;  	if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)  		return -EINVAL;  	octeon_irq_set_ciu_mapping(virq, line, bit,  				   octeon_irq_gpio_chip,  				   octeon_irq_handle_gpio); -  	return 0;  } @@ -1149,6 +1145,7 @@ static void __init octeon_irq_init_ciu(void)  	struct irq_chip *chip_wd;  	struct device_node *gpio_node;  	struct device_node *ciu_node; +	struct irq_domain *ciu_domain = NULL;  	octeon_irq_init_ciu_percpu();  	octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; @@ -1177,31 +1174,6 @@ static void __init octeon_irq_init_ciu(void)  	/* Mips internal */  	octeon_irq_init_core(); -	/* CIU_0 */ -	for (i = 0; i < 16; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); - -	for (i = 0; i < 4; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); -	for (i = 0; i < 4; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); -	for (i = 0; i < 4; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); - -	/* CIU_1 */ -	for (i = 0; i < 16; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); -  	gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");  	if (gpio_node) {  		struct octeon_irq_gpio_domain_data *gpiod; @@ -1219,10 +1191,35 @@ static void __init octeon_irq_init_ciu(void)  	ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");  	if (ciu_node) { -		irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); +		ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);  		of_node_put(ciu_node);  	} else -		pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n"); +		panic("Cannot find device node for cavium,octeon-3860-ciu."); + +	/* CIU_0 */ +	for (i = 0; i < 16; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0); + +	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); +	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); + +	for (i = 0; i < 4; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36); +	for (i = 0; i < 4; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40); + +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46); +	for (i = 0; i < 4; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52); + +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56); +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63); + +	/* CIU_1 */ +	for (i = 0; i < 16; i++) +		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); + +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17);  	/* Enable the CIU lines */  	set_c0_status(STATUSF_IP3 | STATUSF_IP2);  |