forked from mirrors/linux
		
	gpio: Remove dynamic allocation from populate_parent_alloc_arg()
The gpiolib is unique in the way it uses intermediate fwspecs when feeding an interrupt specifier to the parent domain, as it relies on the populate_parent_alloc_arg() callback to perform a dynamic allocation. This is pretty inefficient (we free the structure almost immediately), and the only reason this isn't a stack allocation is that our ThunderX friend uses MSIs rather than a FW-constructed structure. Let's solve it by providing a new type composed of the union of a struct irq_fwspec and a msi_info_t, which satisfies both requirements. This allows us to use a stack allocation, and we can move the handful of users to this new scheme. Also perform some additional cleanup, such as getting rid of the stub versions of the irq_domain_translate_*cell helpers, which are never used when CONFIG_IRQ_DOMAIN_HIERARCHY isn't selected. Tested on a Tegra186. Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Cc: Daniel Palmer <daniel@thingy.jp> Cc: Romain Perier <romain.perier@gmail.com> Cc: Bartosz Golaszewski <brgl@bgdev.pl> Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Jonathan Hunter <jonathanh@nvidia.com> Cc: Robert Richter <rric@kernel.org> Cc: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> Cc: Andy Gross <agross@kernel.org> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> Acked-by: Bartosz Golaszewski <brgl@bgdev.pl> Link: https://lore.kernel.org/r/20220707182314.66610-2-prabhakar.mahadev-lad.rj@bp.renesas.com
This commit is contained in:
		
							parent
							
								
									a111daf0c5
								
							
						
					
					
						commit
						91a29af413
					
				
					 8 changed files with 73 additions and 101 deletions
				
			
		|  | @ -550,15 +550,12 @@ static struct irq_chip msc313_gpio_irqchip = { | ||||||
|  * so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell |  * so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell | ||||||
|  * that puts GIC_SPI into the first cell. |  * that puts GIC_SPI into the first cell. | ||||||
|  */ |  */ | ||||||
| static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc, | static int msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc, | ||||||
| 					     unsigned int parent_hwirq, | 					      union gpio_irq_fwspec *gfwspec, | ||||||
| 					     unsigned int parent_type) | 					      unsigned int parent_hwirq, | ||||||
|  | 					      unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = gc->irq.parent_domain->fwnode; | 	fwspec->fwnode = gc->irq.parent_domain->fwnode; | ||||||
| 	fwspec->param_count = 3; | 	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[1] = parent_hwirq; | ||||||
| 	fwspec->param[2] = parent_type; | 	fwspec->param[2] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip, | static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip, | ||||||
|  |  | ||||||
|  | @ -443,15 +443,12 @@ static int tegra_gpio_child_to_parent_hwirq(struct gpio_chip *chip, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip, | static int tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip, | ||||||
| 					       unsigned int parent_hwirq, | 					     union gpio_irq_fwspec *gfwspec, | ||||||
| 					       unsigned int parent_type) | 					     unsigned int parent_hwirq, | ||||||
|  | 					     unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | ||||||
| 	fwspec->param_count = 3; | 	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[1] = parent_hwirq; | ||||||
| 	fwspec->param[2] = parent_type; | 	fwspec->param[2] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_PM_SLEEP | #ifdef CONFIG_PM_SLEEP | ||||||
|  |  | ||||||
|  | @ -621,16 +621,13 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip, | static int tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip, | ||||||
| 						 unsigned int parent_hwirq, | 						union gpio_irq_fwspec *gfwspec, | ||||||
| 						 unsigned int parent_type) | 						unsigned int parent_hwirq, | ||||||
|  | 						unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct tegra_gpio *gpio = gpiochip_get_data(chip); | 	struct tegra_gpio *gpio = gpiochip_get_data(chip); | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | ||||||
| 	fwspec->param_count = 3; | 	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[1] = parent_hwirq; | ||||||
| 	fwspec->param[2] = parent_type; | 	fwspec->param[2] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip, | static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip, | ||||||
|  |  | ||||||
|  | @ -408,18 +408,15 @@ static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void *thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip, | static int thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip, | ||||||
| 						      unsigned int parent_hwirq, | 						    union gpio_irq_fwspec *gfwspec, | ||||||
| 						      unsigned int parent_type) | 						    unsigned int parent_hwirq, | ||||||
|  | 						    unsigned int parent_type) | ||||||
| { | { | ||||||
| 	msi_alloc_info_t *info; | 	msi_alloc_info_t *info = &gfwspec->msiinfo; | ||||||
| 
 |  | ||||||
| 	info = kmalloc(sizeof(*info), GFP_KERNEL); |  | ||||||
| 	if (!info) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	info->hwirq = parent_hwirq; | 	info->hwirq = parent_hwirq; | ||||||
| 	return info; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int thunderx_gpio_probe(struct pci_dev *pdev, | static int thunderx_gpio_probe(struct pci_dev *pdev, | ||||||
|  |  | ||||||
|  | @ -103,15 +103,12 @@ static int visconti_gpio_child_to_parent_hwirq(struct gpio_chip *gc, | ||||||
| 	return -EINVAL; | 	return -EINVAL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip, | static int visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip, | ||||||
| 						  unsigned int parent_hwirq, | 						union gpio_irq_fwspec *gfwspec, | ||||||
| 						  unsigned int parent_type) | 						unsigned int parent_hwirq, | ||||||
|  | 						unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | ||||||
| 	fwspec->param_count = 3; | 	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[1] = parent_hwirq; | ||||||
| 	fwspec->param[2] = parent_type; | 	fwspec->param[2] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int visconti_gpio_probe(struct platform_device *pdev) | static int visconti_gpio_probe(struct platform_device *pdev) | ||||||
|  |  | ||||||
|  | @ -1107,7 +1107,7 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d, | ||||||
| 	irq_hw_number_t hwirq; | 	irq_hw_number_t hwirq; | ||||||
| 	unsigned int type = IRQ_TYPE_NONE; | 	unsigned int type = IRQ_TYPE_NONE; | ||||||
| 	struct irq_fwspec *fwspec = data; | 	struct irq_fwspec *fwspec = data; | ||||||
| 	void *parent_arg; | 	union gpio_irq_fwspec gpio_parent_fwspec = {}; | ||||||
| 	unsigned int parent_hwirq; | 	unsigned int parent_hwirq; | ||||||
| 	unsigned int parent_type; | 	unsigned int parent_type; | ||||||
| 	struct gpio_irq_chip *girq = &gc->irq; | 	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); | 	irq_set_probe(irq); | ||||||
| 
 | 
 | ||||||
| 	/* This parent only handles asserted level IRQs */ | 	/* This parent only handles asserted level IRQs */ | ||||||
| 	parent_arg = girq->populate_parent_alloc_arg(gc, parent_hwirq, parent_type); | 	ret = girq->populate_parent_alloc_arg(gc, &gpio_parent_fwspec, | ||||||
| 	if (!parent_arg) | 					      parent_hwirq, parent_type); | ||||||
| 		return -ENOMEM; | 	if (ret) | ||||||
|  | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	chip_dbg(gc, "alloc_irqs_parent for %d parent hwirq %d\n", | 	chip_dbg(gc, "alloc_irqs_parent for %d parent hwirq %d\n", | ||||||
| 		  irq, parent_hwirq); | 		  irq, parent_hwirq); | ||||||
| 	irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key); | 	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 | 	 * If the parent irqdomain is msi, the interrupts have already | ||||||
| 	 * been allocated, so the EEXIST is good. | 	 * 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", | 			 "failed to allocate parent hwirq %d for hwirq %lu\n", | ||||||
| 			 parent_hwirq, hwirq); | 			 parent_hwirq, hwirq); | ||||||
| 
 | 
 | ||||||
| 	kfree(parent_arg); |  | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1230,34 +1230,28 @@ static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc) | ||||||
| 	return !!gc->irq.parent_domain; | 	return !!gc->irq.parent_domain; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, | int gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, | ||||||
| 					     unsigned int parent_hwirq, | 					    union gpio_irq_fwspec *gfwspec, | ||||||
| 					     unsigned int parent_type) | 					    unsigned int parent_hwirq, | ||||||
|  | 					    unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = gc->irq.parent_domain->fwnode; | 	fwspec->fwnode = gc->irq.parent_domain->fwnode; | ||||||
| 	fwspec->param_count = 2; | 	fwspec->param_count = 2; | ||||||
| 	fwspec->param[0] = parent_hwirq; | 	fwspec->param[0] = parent_hwirq; | ||||||
| 	fwspec->param[1] = parent_type; | 	fwspec->param[1] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell); | EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell); | ||||||
| 
 | 
 | ||||||
| void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, | int gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, | ||||||
| 					      unsigned int parent_hwirq, | 					     union gpio_irq_fwspec *gfwspec, | ||||||
| 					      unsigned int parent_type) | 					     unsigned int parent_hwirq, | ||||||
|  | 					     unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = gc->irq.parent_domain->fwnode; | 	fwspec->fwnode = gc->irq.parent_domain->fwnode; | ||||||
| 	fwspec->param_count = 4; | 	fwspec->param_count = 4; | ||||||
|  | @ -1266,7 +1260,7 @@ void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, | ||||||
| 	fwspec->param[2] = 0; | 	fwspec->param[2] = 0; | ||||||
| 	fwspec->param[3] = parent_type; | 	fwspec->param[3] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell); | EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -966,16 +966,13 @@ static int pmic_gpio_child_to_parent_hwirq(struct gpio_chip *chip, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void *pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip, | static int pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip, | ||||||
| 					     unsigned int parent_hwirq, | 					    union gpio_irq_fwspec *gfwspec, | ||||||
| 					     unsigned int parent_type) | 					    unsigned int parent_hwirq, | ||||||
|  | 					    unsigned int parent_type) | ||||||
| { | { | ||||||
| 	struct pmic_gpio_state *state = gpiochip_get_data(chip); | 	struct pmic_gpio_state *state = gpiochip_get_data(chip); | ||||||
| 	struct irq_fwspec *fwspec; | 	struct irq_fwspec *fwspec = &gfwspec->fwspec; | ||||||
| 
 |  | ||||||
| 	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL); |  | ||||||
| 	if (!fwspec) |  | ||||||
| 		return NULL; |  | ||||||
| 
 | 
 | ||||||
| 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | 	fwspec->fwnode = chip->irq.parent_domain->fwnode; | ||||||
| 
 | 
 | ||||||
|  | @ -985,7 +982,7 @@ static void *pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip, | ||||||
| 	/* param[2] must be left as 0 */ | 	/* param[2] must be left as 0 */ | ||||||
| 	fwspec->param[3] = parent_type; | 	fwspec->param[3] = parent_type; | ||||||
| 
 | 
 | ||||||
| 	return fwspec; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int pmic_gpio_probe(struct platform_device *pdev) | static int pmic_gpio_probe(struct platform_device *pdev) | ||||||
|  |  | ||||||
|  | @ -12,6 +12,8 @@ | ||||||
| #include <linux/property.h> | #include <linux/property.h> | ||||||
| #include <linux/types.h> | #include <linux/types.h> | ||||||
| 
 | 
 | ||||||
|  | #include <asm/msi.h> | ||||||
|  | 
 | ||||||
| struct gpio_desc; | struct gpio_desc; | ||||||
| struct of_phandle_args; | struct of_phandle_args; | ||||||
| struct device_node; | struct device_node; | ||||||
|  | @ -23,6 +25,13 @@ enum gpio_lookup_flags; | ||||||
| 
 | 
 | ||||||
| struct gpio_chip; | struct gpio_chip; | ||||||
| 
 | 
 | ||||||
|  | union gpio_irq_fwspec { | ||||||
|  | 	struct irq_fwspec	fwspec; | ||||||
|  | #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN | ||||||
|  | 	msi_alloc_info_t	msiinfo; | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| #define GPIO_LINE_DIRECTION_IN	1 | #define GPIO_LINE_DIRECTION_IN	1 | ||||||
| #define GPIO_LINE_DIRECTION_OUT	0 | #define GPIO_LINE_DIRECTION_OUT	0 | ||||||
| 
 | 
 | ||||||
|  | @ -103,9 +112,10 @@ struct gpio_irq_chip { | ||||||
| 	 * variant named &gpiochip_populate_parent_fwspec_fourcell is also | 	 * variant named &gpiochip_populate_parent_fwspec_fourcell is also | ||||||
| 	 * available. | 	 * available. | ||||||
| 	 */ | 	 */ | ||||||
| 	void *(*populate_parent_alloc_arg)(struct gpio_chip *gc, | 	int (*populate_parent_alloc_arg)(struct gpio_chip *gc, | ||||||
| 				       unsigned int parent_hwirq, | 					 union gpio_irq_fwspec *fwspec, | ||||||
| 				       unsigned int parent_type); | 					 unsigned int parent_hwirq, | ||||||
|  | 					 unsigned int parent_type); | ||||||
| 
 | 
 | ||||||
| 	/**
 | 	/**
 | ||||||
| 	 * @child_offset_to_irq: | 	 * @child_offset_to_irq: | ||||||
|  | @ -646,28 +656,14 @@ struct bgpio_pdata { | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY | ||||||
| 
 | 
 | ||||||
| void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, | int gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, | ||||||
|  | 					    union gpio_irq_fwspec *gfwspec, | ||||||
|  | 					    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_hwirq, | ||||||
| 					     unsigned int parent_type); | 					     unsigned int parent_type); | ||||||
| void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, |  | ||||||
| 					      unsigned int parent_hwirq, |  | ||||||
| 					      unsigned int parent_type); |  | ||||||
| 
 |  | ||||||
| #else |  | ||||||
| 
 |  | ||||||
| static inline void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc, |  | ||||||
| 						    unsigned int parent_hwirq, |  | ||||||
| 						    unsigned int parent_type) |  | ||||||
| { |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc, |  | ||||||
| 						     unsigned int parent_hwirq, |  | ||||||
| 						     unsigned int parent_type) |  | ||||||
| { |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */ | #endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Marc Zyngier
						Marc Zyngier