mirror of https://github.com/OpenIPC/firmware.git
				
				
				
			
		
			
				
	
	
		
			77 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Diff
		
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Diff
		
	
	
| --- linux-4.9.37/drivers/gpio/gpio-pl061.c	2017-07-12 16:42:41.000000000 +0300
 | |
| +++ linux-4.9.y/drivers/gpio/gpio-pl061.c	2021-06-07 13:01:33.000000000 +0300
 | |
| @@ -208,6 +208,25 @@
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +#ifdef CONFIG_ARCH_GOKE
 | |
| +static irqreturn_t pl061_irq_handler(int irq, void *data)
 | |
| +{
 | |
| +	unsigned long pending;
 | |
| +	int offset;
 | |
| +	struct gpio_chip *gc = data;
 | |
| +	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
 | |
| +
 | |
| +	pending = readb(chip->base + GPIOMIS);
 | |
| +	writeb(pending, chip->base + GPIOIC);
 | |
| +	if (pending) {
 | |
| +		for_each_set_bit(offset, &pending, PL061_GPIO_NR)
 | |
| +			generic_handle_irq(irq_find_mapping(gc->irqdomain,
 | |
| +							    offset));
 | |
| +	}
 | |
| +
 | |
| +	return IRQ_HANDLED;
 | |
| +}
 | |
| +#else
 | |
|  static void pl061_irq_handler(struct irq_desc *desc)
 | |
|  {
 | |
|  	unsigned long pending;
 | |
| @@ -227,6 +246,7 @@
 | |
|  
 | |
|  	chained_irq_exit(irqchip, desc);
 | |
|  }
 | |
| +#endif
 | |
|  
 | |
|  static void pl061_irq_mask(struct irq_data *d)
 | |
|  {
 | |
| @@ -308,7 +328,17 @@
 | |
|  			return -ENODEV;
 | |
|  		}
 | |
|  	} else {
 | |
| +#ifdef CONFIG_ARCH_GOKE
 | |
| +		if (dev->of_node) {
 | |
| +			i = of_alias_get_id(dev->of_node, "gpio");
 | |
| +			chip->gc.base = i * PL061_GPIO_NR;
 | |
| +		}
 | |
| +
 | |
| +		if (chip->gc.base < 0)
 | |
| +			chip->gc.base = -1;
 | |
| +#else
 | |
|  		chip->gc.base = -1;
 | |
| +#endif
 | |
|  		irq_base = 0;
 | |
|  	}
 | |
|  
 | |
| @@ -353,8 +383,21 @@
 | |
|  		dev_info(&adev->dev, "could not add irqchip\n");
 | |
|  		return ret;
 | |
|  	}
 | |
| +#ifdef CONFIG_ARCH_GOKE
 | |
| +	ret = devm_request_irq(dev, irq, pl061_irq_handler, IRQF_SHARED,
 | |
| +			dev_name(dev), &chip->gc);
 | |
| +	if (ret) {
 | |
| +		dev_info(dev, "request irq failed: %d\n", ret);
 | |
| +		return ret;
 | |
| +	}
 | |
| +
 | |
| +	/* Set the parent IRQ for all affected IRQs */
 | |
| +	for (i = 0; i < chip->gc.ngpio; i++)
 | |
| +		irq_set_parent(irq_find_mapping(chip->gc.irqdomain, i), irq);
 | |
| +#else
 | |
|  	gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip,
 | |
|  				     irq, pl061_irq_handler);
 | |
| +#endif
 | |
|  
 | |
|  	for (i = 0; i < PL061_GPIO_NR; i++) {
 | |
|  		if (pdata) {
 |