diff options
| -rw-r--r-- | drivers/gpio/gpio-pca953x.c | 65 | 
1 files changed, 28 insertions, 37 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 3a68aed9111..1dc99062eb1 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -89,7 +89,6 @@ struct pca953x_chip {  	u8 irq_stat[MAX_BANK];  	u8 irq_trig_raise[MAX_BANK];  	u8 irq_trig_fall[MAX_BANK]; -	int	 irq_base;  	struct irq_domain *domain;  #endif @@ -372,7 +371,7 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)  	struct pca953x_chip *chip;  	chip = container_of(gc, struct pca953x_chip, gpio_chip); -	return chip->irq_base + off; +	return irq_create_mapping(chip->domain, off);  }  static void pca953x_irq_mask(struct irq_data *d) @@ -520,6 +519,27 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)  	return IRQ_HANDLED;  } +static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, +		       irq_hw_number_t hwirq) +{ +	irq_clear_status_flags(irq, IRQ_NOREQUEST); +	irq_set_chip_data(irq, d->host_data); +	irq_set_chip(irq, &pca953x_irq_chip); +	irq_set_nested_thread(irq, true); +#ifdef CONFIG_ARM +	set_irq_flags(irq, IRQF_VALID); +#else +	irq_set_noprobe(irq); +#endif + +	return 0; +} + +static const struct irq_domain_ops pca953x_irq_simple_ops = { +	.map = pca953x_gpio_irq_map, +	.xlate = irq_domain_xlate_twocell, +}; +  static int pca953x_irq_setup(struct pca953x_chip *chip,  			     const struct i2c_device_id *id,  			     int irq_base) @@ -529,7 +549,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,  	if (irq_base != -1  			&& (id->driver_data & PCA_INT)) { -		int lvl;  		switch (chip->chip_type) {  		case PCA953X_TYPE: @@ -552,34 +571,13 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,  			chip->irq_stat[i] &= chip->reg_direction[i];  		mutex_init(&chip->irq_lock); -		chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1); -		if (chip->irq_base < 0) -			goto out_failed; - -		chip->domain = irq_domain_add_legacy(client->dev.of_node, +		chip->domain = irq_domain_add_simple(client->dev.of_node,  						chip->gpio_chip.ngpio, -						chip->irq_base, -						0, -						&irq_domain_simple_ops, +						irq_base, +						&pca953x_irq_simple_ops,  						NULL); -		if (!chip->domain) { -			ret = -ENODEV; -			goto out_irqdesc_free; -		} - -		for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { -			int irq = lvl + chip->irq_base; - -			irq_clear_status_flags(irq, IRQ_NOREQUEST); -			irq_set_chip_data(irq, chip); -			irq_set_chip(irq, &pca953x_irq_chip); -			irq_set_nested_thread(irq, true); -#ifdef CONFIG_ARM -			set_irq_flags(irq, IRQF_VALID); -#else -			irq_set_noprobe(irq); -#endif -		} +		if (!chip->domain) +			return -ENODEV;  		ret = request_threaded_irq(client->irq,  					   NULL, @@ -589,25 +587,18 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,  		if (ret) {  			dev_err(&client->dev, "failed to request irq %d\n",  				client->irq); -			goto out_irqdesc_free; +			return ret;  		}  		chip->gpio_chip.to_irq = pca953x_gpio_to_irq;  	}  	return 0; - -out_irqdesc_free: -	irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); -out_failed: -	chip->irq_base = -1; -	return ret;  }  static void pca953x_irq_teardown(struct pca953x_chip *chip)  {  	if (chip->irq_base != -1) { -		irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);  		free_irq(chip->client->irq, chip);  	}  }  |