diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/gpio-msc313.c | 15 | ||||
| -rw-r--r-- | drivers/gpio/gpio-tegra.c | 15 | ||||
| -rw-r--r-- | drivers/gpio/gpio-tegra186.c | 15 | ||||
| -rw-r--r-- | drivers/gpio/gpio-thunderx.c | 17 | ||||
| -rw-r--r-- | drivers/gpio/gpio-visconti.c | 15 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib.c | 51 | 
6 files changed, 54 insertions, 74 deletions
| diff --git a/drivers/gpio/gpio-msc313.c b/drivers/gpio/gpio-msc313.c index b2c90bdd39d0..52d7b8d99170 100644 --- a/drivers/gpio/gpio-msc313.c +++ b/drivers/gpio/gpio-msc313.c @@ -550,15 +550,12 @@ static struct irq_chip msc313_gpio_irqchip = {   * so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell   * that puts GIC_SPI into the first cell.   */ -static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc, -					     unsigned int parent_hwirq, -					     unsigned int parent_type) +static int msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc, +					      union gpio_irq_fwspec *gfwspec, +					      unsigned int parent_hwirq, +					      unsigned int parent_type)  { -	struct irq_fwspec *fwspec; - -	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); -	if (!fwspec) -		return NULL; +	struct irq_fwspec *fwspec = &gfwspec->fwspec;  	fwspec->fwnode = gc->irq.parent_domain->fwnode;  	fwspec->param_count = 3; @@ -566,7 +563,7 @@ static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,  	fwspec->param[1] = parent_hwirq;  	fwspec->param[2] = parent_type; -	return fwspec; +	return 0;  }  static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip, diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index ff2d2a1f9c73..e4fb4cb38a0f 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -443,15 +443,12 @@ static int tegra_gpio_child_to_parent_hwirq(struct gpio_chip *chip,  	return 0;  } -static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip, -					       unsigned int parent_hwirq, -					       unsigned int parent_type) +static int tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip, +					     union gpio_irq_fwspec *gfwspec, +					     unsigned int parent_hwirq, +					     unsigned int parent_type)  { -	struct irq_fwspec *fwspec; - -	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); -	if (!fwspec) -		return NULL; +	struct irq_fwspec *fwspec = &gfwspec->fwspec;  	fwspec->fwnode = chip->irq.parent_domain->fwnode;  	fwspec->param_count = 3; @@ -459,7 +456,7 @@ static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip,  	fwspec->param[1] = parent_hwirq;  	fwspec->param[2] = parent_type; -	return fwspec; +	return 0;  }  #ifdef CONFIG_PM_SLEEP diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index de28a68daea0..54d9fa7da9c1 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -621,16 +621,13 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain,  	return 0;  } -static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip, -						 unsigned int parent_hwirq, -						 unsigned int parent_type) +static int tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip, +						union gpio_irq_fwspec *gfwspec, +						unsigned int parent_hwirq, +						unsigned int parent_type)  {  	struct tegra_gpio *gpio = gpiochip_get_data(chip); -	struct irq_fwspec *fwspec; - -	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); -	if (!fwspec) -		return NULL; +	struct irq_fwspec *fwspec = &gfwspec->fwspec;  	fwspec->fwnode = chip->irq.parent_domain->fwnode;  	fwspec->param_count = 3; @@ -638,7 +635,7 @@ static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,  	fwspec->param[1] = parent_hwirq;  	fwspec->param[2] = parent_type; -	return fwspec; +	return 0;  }  static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip, diff --git a/drivers/gpio/gpio-thunderx.c b/drivers/gpio/gpio-thunderx.c index 9f66deab46ea..cc62c6e64103 100644 --- a/drivers/gpio/gpio-thunderx.c +++ b/drivers/gpio/gpio-thunderx.c @@ -15,8 +15,6 @@  #include <linux/module.h>  #include <linux/pci.h>  #include <linux/spinlock.h> -#include <asm-generic/msi.h> -  #define GPIO_RX_DAT	0x0  #define GPIO_TX_SET	0x8 @@ -408,18 +406,15 @@ static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,  	return 0;  } -static void *thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip, -						      unsigned int parent_hwirq, -						      unsigned int parent_type) +static int thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip, +						    union gpio_irq_fwspec *gfwspec, +						    unsigned int parent_hwirq, +						    unsigned int parent_type)  { -	msi_alloc_info_t *info; - -	info = kmalloc(sizeof(*info), GFP_KERNEL); -	if (!info) -		return NULL; +	msi_alloc_info_t *info = &gfwspec->msiinfo;  	info->hwirq = parent_hwirq; -	return info; +	return 0;  }  static int thunderx_gpio_probe(struct pci_dev *pdev, diff --git a/drivers/gpio/gpio-visconti.c b/drivers/gpio/gpio-visconti.c index e6534ea1eaa7..5e108ba9956a 100644 --- a/drivers/gpio/gpio-visconti.c +++ b/drivers/gpio/gpio-visconti.c @@ -103,15 +103,12 @@ static int visconti_gpio_child_to_parent_hwirq(struct gpio_chip *gc,  	return -EINVAL;  } -static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip, -						  unsigned int parent_hwirq, -						  unsigned int parent_type) +static int visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip, +						union gpio_irq_fwspec *gfwspec, +						unsigned int parent_hwirq, +						unsigned int parent_type)  { -	struct irq_fwspec *fwspec; - -	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); -	if (!fwspec) -		return NULL; +	struct irq_fwspec *fwspec = &gfwspec->fwspec;  	fwspec->fwnode = chip->irq.parent_domain->fwnode;  	fwspec->param_count = 3; @@ -119,7 +116,7 @@ static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,  	fwspec->param[1] = parent_hwirq;  	fwspec->param[2] = parent_type; -	return fwspec; +	return 0;  }  static int visconti_gpio_probe(struct platform_device *pdev) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9535f48e18d1..68d9f95d7799 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1107,7 +1107,7 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,  	irq_hw_number_t hwirq;  	unsigned int type = IRQ_TYPE_NONE;  	struct irq_fwspec *fwspec = data; -	void *parent_arg; +	union gpio_irq_fwspec gpio_parent_fwspec = {};  	unsigned int parent_hwirq;  	unsigned int parent_type;  	struct gpio_irq_chip *girq = &gc->irq; @@ -1147,14 +1147,15 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,  	irq_set_probe(irq);  	/* This parent only handles asserted level IRQs */ -	parent_arg = girq->populate_parent_alloc_arg(gc, parent_hwirq, parent_type); -	if (!parent_arg) -		return -ENOMEM; +	ret = girq->populate_parent_alloc_arg(gc, &gpio_parent_fwspec, +					      parent_hwirq, parent_type); +	if (ret) +		return ret;  	chip_dbg(gc, "alloc_irqs_parent for %d parent hwirq %d\n",  		  irq, parent_hwirq);  	irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key); -	ret = irq_domain_alloc_irqs_parent(d, irq, 1, parent_arg); +	ret = irq_domain_alloc_irqs_parent(d, irq, 1, &gpio_parent_fwspec);  	/*  	 * If the parent irqdomain is msi, the interrupts have already  	 * been allocated, so the EEXIST is good. @@ -1166,7 +1167,6 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,  			 "failed to allocate parent hwirq %d for hwirq %lu\n",  			 parent_hwirq, hwirq); -	kfree(parent_arg);  	return ret;  } @@ -1181,15 +1181,18 @@ static void gpiochip_hierarchy_setup_domain_ops(struct irq_domain_ops *ops)  	ops->activate = gpiochip_irq_domain_activate;  	ops->deactivate = gpiochip_irq_domain_deactivate;  	ops->alloc = gpiochip_hierarchy_irq_domain_alloc; -	ops->free = irq_domain_free_irqs_common;  	/* -	 * We only allow overriding the translate() function for +	 * We only allow overriding the translate() and free() functions for  	 * hierarchical chips, and this should only be done if the user -	 * really need something other than 1:1 translation. +	 * really need something other than 1:1 translation for translate() +	 * callback and free if user wants to free up any resources which +	 * were allocated during callbacks, for example populate_parent_alloc_arg.  	 */  	if (!ops->translate)  		ops->translate = gpiochip_hierarchy_irq_domain_translate; +	if (!ops->free) +		ops->free = irq_domain_free_irqs_common;  }  static int gpiochip_hierarchy_add_domain(struct gpio_chip *gc) @@ -1230,34 +1233,28 @@ static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc)  	return !!gc->irq.parent_domain;  } -void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, -					     unsigned int parent_hwirq, -					     unsigned int parent_type) +int gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, +					    union gpio_irq_fwspec *gfwspec, +					    unsigned int parent_hwirq, +					    unsigned int parent_type)  { -	struct irq_fwspec *fwspec; - -	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); -	if (!fwspec) -		return NULL; +	struct irq_fwspec *fwspec = &gfwspec->fwspec;  	fwspec->fwnode = gc->irq.parent_domain->fwnode;  	fwspec->param_count = 2;  	fwspec->param[0] = parent_hwirq;  	fwspec->param[1] = parent_type; -	return fwspec; +	return 0;  }  EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell); -void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, -					      unsigned int parent_hwirq, -					      unsigned int parent_type) +int gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, +					     union gpio_irq_fwspec *gfwspec, +					     unsigned int parent_hwirq, +					     unsigned int parent_type)  { -	struct irq_fwspec *fwspec; - -	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); -	if (!fwspec) -		return NULL; +	struct irq_fwspec *fwspec = &gfwspec->fwspec;  	fwspec->fwnode = gc->irq.parent_domain->fwnode;  	fwspec->param_count = 4; @@ -1266,7 +1263,7 @@ void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,  	fwspec->param[2] = 0;  	fwspec->param[3] = parent_type; -	return fwspec; +	return 0;  }  EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell); |