mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	gpio: pl061: Make the irqchip immutable
Prevent gpiolib from messing with the irqchip by advertising the irq_chip structure as immutable, making it const, and adding the various calls that gpiolib relies upon. Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220419141846.598305-6-maz@kernel.org
This commit is contained in:
		
							parent
							
								
									bba00555ed
								
							
						
					
					
						commit
						15d8c14ac8
					
				
					 1 changed files with 23 additions and 9 deletions
				
			
		|  | @ -52,7 +52,6 @@ struct pl061 { | ||||||
| 
 | 
 | ||||||
| 	void __iomem		*base; | 	void __iomem		*base; | ||||||
| 	struct gpio_chip	gc; | 	struct gpio_chip	gc; | ||||||
| 	struct irq_chip		irq_chip; |  | ||||||
| 	int			parent_irq; | 	int			parent_irq; | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_PM | #ifdef CONFIG_PM | ||||||
|  | @ -241,6 +240,8 @@ static void pl061_irq_mask(struct irq_data *d) | ||||||
| 	gpioie = readb(pl061->base + GPIOIE) & ~mask; | 	gpioie = readb(pl061->base + GPIOIE) & ~mask; | ||||||
| 	writeb(gpioie, pl061->base + GPIOIE); | 	writeb(gpioie, pl061->base + GPIOIE); | ||||||
| 	raw_spin_unlock(&pl061->lock); | 	raw_spin_unlock(&pl061->lock); | ||||||
|  | 
 | ||||||
|  | 	gpiochip_disable_irq(gc, d->hwirq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void pl061_irq_unmask(struct irq_data *d) | static void pl061_irq_unmask(struct irq_data *d) | ||||||
|  | @ -250,6 +251,8 @@ static void pl061_irq_unmask(struct irq_data *d) | ||||||
| 	u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); | 	u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); | ||||||
| 	u8 gpioie; | 	u8 gpioie; | ||||||
| 
 | 
 | ||||||
|  | 	gpiochip_enable_irq(gc, d->hwirq); | ||||||
|  | 
 | ||||||
| 	raw_spin_lock(&pl061->lock); | 	raw_spin_lock(&pl061->lock); | ||||||
| 	gpioie = readb(pl061->base + GPIOIE) | mask; | 	gpioie = readb(pl061->base + GPIOIE) | mask; | ||||||
| 	writeb(gpioie, pl061->base + GPIOIE); | 	writeb(gpioie, pl061->base + GPIOIE); | ||||||
|  | @ -283,6 +286,24 @@ static int pl061_irq_set_wake(struct irq_data *d, unsigned int state) | ||||||
| 	return irq_set_irq_wake(pl061->parent_irq, state); | 	return irq_set_irq_wake(pl061->parent_irq, state); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void pl061_irq_print_chip(struct irq_data *data, struct seq_file *p) | ||||||
|  | { | ||||||
|  | 	struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | ||||||
|  | 
 | ||||||
|  | 	seq_printf(p, dev_name(gc->parent)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct irq_chip pl061_irq_chip = { | ||||||
|  | 	.irq_ack		= pl061_irq_ack, | ||||||
|  | 	.irq_mask		= pl061_irq_mask, | ||||||
|  | 	.irq_unmask		= pl061_irq_unmask, | ||||||
|  | 	.irq_set_type		= pl061_irq_type, | ||||||
|  | 	.irq_set_wake		= pl061_irq_set_wake, | ||||||
|  | 	.irq_print_chip		= pl061_irq_print_chip, | ||||||
|  | 	.flags			= IRQCHIP_IMMUTABLE, | ||||||
|  | 	GPIOCHIP_IRQ_RESOURCE_HELPERS, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static int pl061_probe(struct amba_device *adev, const struct amba_id *id) | static int pl061_probe(struct amba_device *adev, const struct amba_id *id) | ||||||
| { | { | ||||||
| 	struct device *dev = &adev->dev; | 	struct device *dev = &adev->dev; | ||||||
|  | @ -315,13 +336,6 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * irq_chip support | 	 * irq_chip support | ||||||
| 	 */ | 	 */ | ||||||
| 	pl061->irq_chip.name = dev_name(dev); |  | ||||||
| 	pl061->irq_chip.irq_ack	= pl061_irq_ack; |  | ||||||
| 	pl061->irq_chip.irq_mask = pl061_irq_mask; |  | ||||||
| 	pl061->irq_chip.irq_unmask = pl061_irq_unmask; |  | ||||||
| 	pl061->irq_chip.irq_set_type = pl061_irq_type; |  | ||||||
| 	pl061->irq_chip.irq_set_wake = pl061_irq_set_wake; |  | ||||||
| 
 |  | ||||||
| 	writeb(0, pl061->base + GPIOIE); /* disable irqs */ | 	writeb(0, pl061->base + GPIOIE); /* disable irqs */ | ||||||
| 	irq = adev->irq[0]; | 	irq = adev->irq[0]; | ||||||
| 	if (!irq) | 	if (!irq) | ||||||
|  | @ -329,7 +343,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) | ||||||
| 	pl061->parent_irq = irq; | 	pl061->parent_irq = irq; | ||||||
| 
 | 
 | ||||||
| 	girq = &pl061->gc.irq; | 	girq = &pl061->gc.irq; | ||||||
| 	girq->chip = &pl061->irq_chip; | 	gpio_irq_chip_set_chip(girq, &pl061_irq_chip); | ||||||
| 	girq->parent_handler = pl061_irq_handler; | 	girq->parent_handler = pl061_irq_handler; | ||||||
| 	girq->num_parents = 1; | 	girq->num_parents = 1; | ||||||
| 	girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), | 	girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Marc Zyngier
						Marc Zyngier