diff options
Diffstat (limited to 'drivers/gpio')
37 files changed, 643 insertions, 551 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 45764ec3b2eb..b01961999ced 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -353,8 +353,8 @@ config GPIO_IOP  config GPIO_IXP4XX  	bool "Intel IXP4xx GPIO" -	depends on ARM # For <asm/mach-types.h>  	depends on ARCH_IXP4XX +	depends on OF  	select GPIO_GENERIC  	select GPIOLIB_IRQCHIP  	select IRQ_DOMAIN_HIERARCHY @@ -363,6 +363,7 @@ config GPIO_IXP4XX  	  IXP4xx series of chips.  	  If unsure, say N. +  config GPIO_LOGICVC  	tristate "Xylon LogiCVC GPIO support"  	depends on MFD_SYSCON && OF @@ -674,10 +675,10 @@ config GPIO_UNIPHIER  config GPIO_VF610  	def_bool y -	depends on ARCH_MXC && SOC_VF610 +	depends on ARCH_MXC  	select GPIOLIB_IRQCHIP  	help -	  Say yes here to support Vybrid vf610 GPIOs. +	  Say yes here to support i.MX or Vybrid vf610 GPIOs.  config GPIO_VISCONTI  	tristate "Toshiba Visconti GPIO support" diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 6bf41040c41f..f118ad9bcd33 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -49,7 +49,7 @@ struct dio48e_gpio {  	unsigned char out_state[6];  	unsigned char control[2];  	raw_spinlock_t lock; -	unsigned int base; +	void __iomem *base;  	unsigned char irq_mask;  }; @@ -70,7 +70,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned int offs  	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);  	const unsigned int io_port = offset / 8;  	const unsigned int control_port = io_port / 3; -	const unsigned int control_addr = dio48egpio->base + 3 + control_port * 4; +	void __iomem *const control_addr = dio48egpio->base + 3 + control_port * 4;  	unsigned long flags;  	unsigned int control; @@ -95,9 +95,9 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned int offs  	}  	control = BIT(7) | dio48egpio->control[control_port]; -	outb(control, control_addr); +	iowrite8(control, control_addr);  	control &= ~BIT(7); -	outb(control, control_addr); +	iowrite8(control, control_addr);  	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); @@ -111,7 +111,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned int off  	const unsigned int io_port = offset / 8;  	const unsigned int control_port = io_port / 3;  	const unsigned int mask = BIT(offset % 8); -	const unsigned int control_addr = dio48egpio->base + 3 + control_port * 4; +	void __iomem *const control_addr = dio48egpio->base + 3 + control_port * 4;  	const unsigned int out_port = (io_port > 2) ? io_port + 1 : io_port;  	unsigned long flags;  	unsigned int control; @@ -142,12 +142,12 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned int off  		dio48egpio->out_state[io_port] &= ~mask;  	control = BIT(7) | dio48egpio->control[control_port]; -	outb(control, control_addr); +	iowrite8(control, control_addr); -	outb(dio48egpio->out_state[io_port], dio48egpio->base + out_port); +	iowrite8(dio48egpio->out_state[io_port], dio48egpio->base + out_port);  	control &= ~BIT(7); -	outb(control, control_addr); +	iowrite8(control, control_addr);  	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); @@ -171,7 +171,7 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned int offset)  		return -EINVAL;  	} -	port_state = inb(dio48egpio->base + in_port); +	port_state = ioread8(dio48egpio->base + in_port);  	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags); @@ -186,7 +186,7 @@ static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,  	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);  	unsigned long offset;  	unsigned long gpio_mask; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long port_state;  	/* clear bits array to a clean slate */ @@ -194,7 +194,7 @@ static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,  	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {  		port_addr = dio48egpio->base + ports[offset / 8]; -		port_state = inb(port_addr) & gpio_mask; +		port_state = ioread8(port_addr) & gpio_mask;  		bitmap_set_value8(bits, port_state, offset);  	} @@ -217,7 +217,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned int offset, int val  	else  		dio48egpio->out_state[port] &= ~mask; -	outb(dio48egpio->out_state[port], dio48egpio->base + out_port); +	iowrite8(dio48egpio->out_state[port], dio48egpio->base + out_port);  	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);  } @@ -229,7 +229,7 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,  	unsigned long offset;  	unsigned long gpio_mask;  	size_t index; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long bitmask;  	unsigned long flags; @@ -244,7 +244,7 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,  		/* update output state data and set device gpio register */  		dio48egpio->out_state[index] &= ~gpio_mask;  		dio48egpio->out_state[index] |= bitmask; -		outb(dio48egpio->out_state[index], port_addr); +		iowrite8(dio48egpio->out_state[index], port_addr);  		raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);  	} @@ -274,7 +274,7 @@ static void dio48e_irq_mask(struct irq_data *data)  	if (!dio48egpio->irq_mask)  		/* disable interrupts */ -		inb(dio48egpio->base + 0xB); +		ioread8(dio48egpio->base + 0xB);  	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);  } @@ -294,8 +294,8 @@ static void dio48e_irq_unmask(struct irq_data *data)  	if (!dio48egpio->irq_mask) {  		/* enable interrupts */ -		outb(0x00, dio48egpio->base + 0xF); -		outb(0x00, dio48egpio->base + 0xB); +		iowrite8(0x00, dio48egpio->base + 0xF); +		iowrite8(0x00, dio48egpio->base + 0xB);  	}  	if (offset == 19) @@ -341,7 +341,7 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)  	raw_spin_lock(&dio48egpio->lock); -	outb(0x00, dio48egpio->base + 0xF); +	iowrite8(0x00, dio48egpio->base + 0xF);  	raw_spin_unlock(&dio48egpio->lock); @@ -373,7 +373,7 @@ static int dio48e_irq_init_hw(struct gpio_chip *gc)  	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(gc);  	/* Disable IRQ by default */ -	inb(dio48egpio->base + 0xB); +	ioread8(dio48egpio->base + 0xB);  	return 0;  } @@ -395,6 +395,10 @@ static int dio48e_probe(struct device *dev, unsigned int id)  		return -EBUSY;  	} +	dio48egpio->base = devm_ioport_map(dev, base[id], DIO48E_EXTENT); +	if (!dio48egpio->base) +		return -ENOMEM; +  	dio48egpio->chip.label = name;  	dio48egpio->chip.parent = dev;  	dio48egpio->chip.owner = THIS_MODULE; @@ -408,7 +412,6 @@ static int dio48e_probe(struct device *dev, unsigned int id)  	dio48egpio->chip.get_multiple = dio48e_gpio_get_multiple;  	dio48egpio->chip.set = dio48e_gpio_set;  	dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple; -	dio48egpio->base = base[id];  	girq = &dio48egpio->chip.irq;  	girq->chip = &dio48e_irqchip; @@ -423,16 +426,16 @@ static int dio48e_probe(struct device *dev, unsigned int id)  	raw_spin_lock_init(&dio48egpio->lock);  	/* initialize all GPIO as output */ -	outb(0x80, base[id] + 3); -	outb(0x00, base[id]); -	outb(0x00, base[id] + 1); -	outb(0x00, base[id] + 2); -	outb(0x00, base[id] + 3); -	outb(0x80, base[id] + 7); -	outb(0x00, base[id] + 4); -	outb(0x00, base[id] + 5); -	outb(0x00, base[id] + 6); -	outb(0x00, base[id] + 7); +	iowrite8(0x80, dio48egpio->base + 3); +	iowrite8(0x00, dio48egpio->base); +	iowrite8(0x00, dio48egpio->base + 1); +	iowrite8(0x00, dio48egpio->base + 2); +	iowrite8(0x00, dio48egpio->base + 3); +	iowrite8(0x80, dio48egpio->base + 7); +	iowrite8(0x00, dio48egpio->base + 4); +	iowrite8(0x00, dio48egpio->base + 5); +	iowrite8(0x00, dio48egpio->base + 6); +	iowrite8(0x00, dio48egpio->base + 7);  	err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);  	if (err) { diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index 34be7dd9f5b9..9521ece3ebef 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -47,7 +47,7 @@ struct idi_48_gpio {  	raw_spinlock_t lock;  	spinlock_t ack_lock;  	unsigned char irq_mask[6]; -	unsigned base; +	void __iomem *base;  	unsigned char cos_enb;  }; @@ -66,15 +66,15 @@ static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)  	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);  	unsigned i;  	static const unsigned int register_offset[6] = { 0, 1, 2, 4, 5, 6 }; -	unsigned base_offset; +	void __iomem *port_addr;  	unsigned mask;  	for (i = 0; i < 48; i += 8)  		if (offset < i + 8) { -			base_offset = register_offset[i / 8]; +			port_addr = idi48gpio->base + register_offset[i / 8];  			mask = BIT(offset - i); -			return !!(inb(idi48gpio->base + base_offset) & mask); +			return !!(ioread8(port_addr) & mask);  		}  	/* The following line should never execute since offset < 48 */ @@ -88,7 +88,7 @@ static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,  	unsigned long offset;  	unsigned long gpio_mask;  	static const size_t ports[] = { 0, 1, 2, 4, 5, 6 }; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long port_state;  	/* clear bits array to a clean slate */ @@ -96,7 +96,7 @@ static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,  	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {  		port_addr = idi48gpio->base + ports[offset / 8]; -		port_state = inb(port_addr) & gpio_mask; +		port_state = ioread8(port_addr) & gpio_mask;  		bitmap_set_value8(bits, port_state, offset);  	} @@ -130,7 +130,7 @@ static void idi_48_irq_mask(struct irq_data *data)  				raw_spin_lock_irqsave(&idi48gpio->lock, flags); -				outb(idi48gpio->cos_enb, idi48gpio->base + 7); +				iowrite8(idi48gpio->cos_enb, idi48gpio->base + 7);  				raw_spin_unlock_irqrestore(&idi48gpio->lock, flags);  			} @@ -163,7 +163,7 @@ static void idi_48_irq_unmask(struct irq_data *data)  				raw_spin_lock_irqsave(&idi48gpio->lock, flags); -				outb(idi48gpio->cos_enb, idi48gpio->base + 7); +				iowrite8(idi48gpio->cos_enb, idi48gpio->base + 7);  				raw_spin_unlock_irqrestore(&idi48gpio->lock, flags);  			} @@ -204,7 +204,7 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)  	raw_spin_lock(&idi48gpio->lock); -	cos_status = inb(idi48gpio->base + 7); +	cos_status = ioread8(idi48gpio->base + 7);  	raw_spin_unlock(&idi48gpio->lock); @@ -250,8 +250,8 @@ static int idi_48_irq_init_hw(struct gpio_chip *gc)  	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(gc);  	/* Disable IRQ by default */ -	outb(0, idi48gpio->base + 7); -	inb(idi48gpio->base + 7); +	iowrite8(0, idi48gpio->base + 7); +	ioread8(idi48gpio->base + 7);  	return 0;  } @@ -273,6 +273,10 @@ static int idi_48_probe(struct device *dev, unsigned int id)  		return -EBUSY;  	} +	idi48gpio->base = devm_ioport_map(dev, base[id], IDI_48_EXTENT); +	if (!idi48gpio->base) +		return -ENOMEM; +  	idi48gpio->chip.label = name;  	idi48gpio->chip.parent = dev;  	idi48gpio->chip.owner = THIS_MODULE; @@ -283,7 +287,6 @@ static int idi_48_probe(struct device *dev, unsigned int id)  	idi48gpio->chip.direction_input = idi_48_gpio_direction_input;  	idi48gpio->chip.get = idi_48_gpio_get;  	idi48gpio->chip.get_multiple = idi_48_gpio_get_multiple; -	idi48gpio->base = base[id];  	girq = &idi48gpio->chip.irq;  	girq->chip = &idi_48_irqchip; diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index c68ed1a135fa..45f7ad8573e1 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -44,7 +44,7 @@ struct idio_16_gpio {  	struct gpio_chip chip;  	raw_spinlock_t lock;  	unsigned long irq_mask; -	unsigned int base; +	void __iomem *base;  	unsigned int out_state;  }; @@ -79,9 +79,9 @@ static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)  		return -EINVAL;  	if (offset < 24) -		return !!(inb(idio16gpio->base + 1) & mask); +		return !!(ioread8(idio16gpio->base + 1) & mask); -	return !!(inb(idio16gpio->base + 5) & (mask>>8)); +	return !!(ioread8(idio16gpio->base + 5) & (mask>>8));  }  static int idio_16_gpio_get_multiple(struct gpio_chip *chip, @@ -91,9 +91,9 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip,  	*bits = 0;  	if (*mask & GENMASK(23, 16)) -		*bits |= (unsigned long)inb(idio16gpio->base + 1) << 16; +		*bits |= (unsigned long)ioread8(idio16gpio->base + 1) << 16;  	if (*mask & GENMASK(31, 24)) -		*bits |= (unsigned long)inb(idio16gpio->base + 5) << 24; +		*bits |= (unsigned long)ioread8(idio16gpio->base + 5) << 24;  	return 0;  } @@ -116,9 +116,9 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,  		idio16gpio->out_state &= ~mask;  	if (offset > 7) -		outb(idio16gpio->out_state >> 8, idio16gpio->base + 4); +		iowrite8(idio16gpio->out_state >> 8, idio16gpio->base + 4);  	else -		outb(idio16gpio->out_state, idio16gpio->base); +		iowrite8(idio16gpio->out_state, idio16gpio->base);  	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);  } @@ -135,9 +135,9 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip,  	idio16gpio->out_state |= *mask & *bits;  	if (*mask & 0xFF) -		outb(idio16gpio->out_state, idio16gpio->base); +		iowrite8(idio16gpio->out_state, idio16gpio->base);  	if ((*mask >> 8) & 0xFF) -		outb(idio16gpio->out_state >> 8, idio16gpio->base + 4); +		iowrite8(idio16gpio->out_state >> 8, idio16gpio->base + 4);  	raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);  } @@ -158,7 +158,7 @@ static void idio_16_irq_mask(struct irq_data *data)  	if (!idio16gpio->irq_mask) {  		raw_spin_lock_irqsave(&idio16gpio->lock, flags); -		outb(0, idio16gpio->base + 2); +		iowrite8(0, idio16gpio->base + 2);  		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);  	} @@ -177,7 +177,7 @@ static void idio_16_irq_unmask(struct irq_data *data)  	if (!prev_irq_mask) {  		raw_spin_lock_irqsave(&idio16gpio->lock, flags); -		inb(idio16gpio->base + 2); +		ioread8(idio16gpio->base + 2);  		raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);  	} @@ -212,7 +212,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)  	raw_spin_lock(&idio16gpio->lock); -	outb(0, idio16gpio->base + 1); +	iowrite8(0, idio16gpio->base + 1);  	raw_spin_unlock(&idio16gpio->lock); @@ -232,8 +232,8 @@ static int idio_16_irq_init_hw(struct gpio_chip *gc)  	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);  	/* Disable IRQ by default */ -	outb(0, idio16gpio->base + 2); -	outb(0, idio16gpio->base + 1); +	iowrite8(0, idio16gpio->base + 2); +	iowrite8(0, idio16gpio->base + 1);  	return 0;  } @@ -255,6 +255,10 @@ static int idio_16_probe(struct device *dev, unsigned int id)  		return -EBUSY;  	} +	idio16gpio->base = devm_ioport_map(dev, base[id], IDIO_16_EXTENT); +	if (!idio16gpio->base) +		return -ENOMEM; +  	idio16gpio->chip.label = name;  	idio16gpio->chip.parent = dev;  	idio16gpio->chip.owner = THIS_MODULE; @@ -268,7 +272,6 @@ static int idio_16_probe(struct device *dev, unsigned int id)  	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;  	idio16gpio->chip.set = idio_16_gpio_set;  	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; -	idio16gpio->base = base[id];  	idio16gpio->out_state = 0xFFFF;  	girq = &idio16gpio->chip.irq; diff --git a/drivers/gpio/gpio-amdpt.c b/drivers/gpio/gpio-amdpt.c index 8cfb353c3abb..07c6d090058d 100644 --- a/drivers/gpio/gpio-amdpt.c +++ b/drivers/gpio/gpio-amdpt.c @@ -36,19 +36,19 @@ static int pt_gpio_request(struct gpio_chip *gc, unsigned offset)  	dev_dbg(gc->parent, "pt_gpio_request offset=%x\n", offset); -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);  	if (using_pins & BIT(offset)) {  		dev_warn(gc->parent, "PT GPIO pin %x reconfigured\n",  			 offset); -		spin_unlock_irqrestore(&gc->bgpio_lock, flags); +		raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  		return -EINVAL;  	}  	writel(using_pins | BIT(offset), pt_gpio->reg_base + PT_SYNC_REG); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } @@ -59,13 +59,13 @@ static void pt_gpio_free(struct gpio_chip *gc, unsigned offset)  	unsigned long flags;  	u32 using_pins; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);  	using_pins &= ~BIT(offset);  	writel(using_pins, pt_gpio->reg_base + PT_SYNC_REG); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	dev_dbg(gc->parent, "pt_gpio_free offset=%x\n", offset);  } diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 74ef89248867..6b7439b44690 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c @@ -92,9 +92,9 @@ brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)  	unsigned long status;  	unsigned long flags; -	spin_lock_irqsave(&bank->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);  	status = __brcmstb_gpio_get_active_irqs(bank); -	spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);  	return status;  } @@ -114,14 +114,14 @@ static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,  	u32 imask;  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id));  	if (enable)  		imask |= mask;  	else  		imask &= ~mask;  	gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) @@ -204,7 +204,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)  		return -EINVAL;  	} -	spin_lock_irqsave(&bank->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);  	iedge_config = bank->gc.read_reg(priv->reg_base +  			GIO_EC(bank->id)) & ~mask; @@ -220,7 +220,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)  	bank->gc.write_reg(priv->reg_base + GIO_LEVEL(bank->id),  			ilevel | level); -	spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);  	return 0;  } diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c index 562f8f7e7d1f..137aea49ba02 100644 --- a/drivers/gpio/gpio-cadence.c +++ b/drivers/gpio/gpio-cadence.c @@ -41,12 +41,12 @@ static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)  	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);  	unsigned long flags; -	spin_lock_irqsave(&chip->bgpio_lock, flags); +	raw_spin_lock_irqsave(&chip->bgpio_lock, flags);  	iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),  		  cgpio->regs + CDNS_GPIO_BYPASS_MODE); -	spin_unlock_irqrestore(&chip->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);  	return 0;  } @@ -55,13 +55,13 @@ static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)  	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);  	unsigned long flags; -	spin_lock_irqsave(&chip->bgpio_lock, flags); +	raw_spin_lock_irqsave(&chip->bgpio_lock, flags);  	iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |  		  (BIT(offset) & cgpio->bypass_orig),  		  cgpio->regs + CDNS_GPIO_BYPASS_MODE); -	spin_unlock_irqrestore(&chip->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);  }  static void cdns_gpio_irq_mask(struct irq_data *d) @@ -90,7 +90,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)  	u32 mask = BIT(d->hwirq);  	int ret = 0; -	spin_lock_irqsave(&chip->bgpio_lock, flags); +	raw_spin_lock_irqsave(&chip->bgpio_lock, flags);  	int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;  	int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask; @@ -115,7 +115,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)  	iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);  err_irq_type: -	spin_unlock_irqrestore(&chip->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);  	return ret;  } diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index b0f3aca61974..04afe728e187 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -95,7 +95,6 @@ struct dwapb_context {  #endif  struct dwapb_gpio_port_irqchip { -	struct irq_chip		irqchip;  	unsigned int		nr_irqs;  	unsigned int		irq[DWAPB_MAX_GPIOS];  }; @@ -243,35 +242,41 @@ static void dwapb_irq_ack(struct irq_data *d)  	u32 val = BIT(irqd_to_hwirq(d));  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	dwapb_write(gpio, GPIO_PORTA_EOI, val); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void dwapb_irq_mask(struct irq_data *d)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);  	struct dwapb_gpio *gpio = to_dwapb_gpio(gc); +	irq_hw_number_t hwirq = irqd_to_hwirq(d);  	unsigned long flags;  	u32 val; -	spin_lock_irqsave(&gc->bgpio_lock, flags); -	val = dwapb_read(gpio, GPIO_INTMASK) | BIT(irqd_to_hwirq(d)); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags); +	val = dwapb_read(gpio, GPIO_INTMASK) | BIT(hwirq);  	dwapb_write(gpio, GPIO_INTMASK, val); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); + +	gpiochip_disable_irq(gc, hwirq);  }  static void dwapb_irq_unmask(struct irq_data *d)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);  	struct dwapb_gpio *gpio = to_dwapb_gpio(gc); +	irq_hw_number_t hwirq = irqd_to_hwirq(d);  	unsigned long flags;  	u32 val; -	spin_lock_irqsave(&gc->bgpio_lock, flags); -	val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(irqd_to_hwirq(d)); +	gpiochip_enable_irq(gc, hwirq); + +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags); +	val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(hwirq);  	dwapb_write(gpio, GPIO_INTMASK, val); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void dwapb_irq_enable(struct irq_data *d) @@ -281,11 +286,11 @@ static void dwapb_irq_enable(struct irq_data *d)  	unsigned long flags;  	u32 val; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	val = dwapb_read(gpio, GPIO_INTEN);  	val |= BIT(irqd_to_hwirq(d));  	dwapb_write(gpio, GPIO_INTEN, val); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void dwapb_irq_disable(struct irq_data *d) @@ -295,11 +300,11 @@ static void dwapb_irq_disable(struct irq_data *d)  	unsigned long flags;  	u32 val; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	val = dwapb_read(gpio, GPIO_INTEN);  	val &= ~BIT(irqd_to_hwirq(d));  	dwapb_write(gpio, GPIO_INTEN, val); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static int dwapb_irq_set_type(struct irq_data *d, u32 type) @@ -309,7 +314,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)  	irq_hw_number_t bit = irqd_to_hwirq(d);  	unsigned long level, polarity, flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);  	polarity = dwapb_read(gpio, GPIO_INT_POLARITY); @@ -344,7 +349,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)  	dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level);  	if (type != IRQ_TYPE_EDGE_BOTH)  		dwapb_write(gpio, GPIO_INT_POLARITY, polarity); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } @@ -364,8 +369,23 @@ static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)  	return 0;  } +#else +#define dwapb_irq_set_wake	NULL  #endif +static const struct irq_chip dwapb_irq_chip = { +	.name		= DWAPB_DRIVER_NAME, +	.irq_ack	= dwapb_irq_ack, +	.irq_mask	= dwapb_irq_mask, +	.irq_unmask	= dwapb_irq_unmask, +	.irq_set_type	= dwapb_irq_set_type, +	.irq_enable	= dwapb_irq_enable, +	.irq_disable	= dwapb_irq_disable, +	.irq_set_wake	= dwapb_irq_set_wake, +	.flags		= IRQCHIP_IMMUTABLE, +	GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; +  static int dwapb_gpio_set_debounce(struct gpio_chip *gc,  				   unsigned offset, unsigned debounce)  { @@ -374,7 +394,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,  	unsigned long flags, val_deb;  	unsigned long mask = BIT(offset); -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);  	if (debounce) @@ -383,7 +403,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,  		val_deb &= ~mask;  	dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } @@ -439,16 +459,6 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,  	girq->default_type = IRQ_TYPE_NONE;  	port->pirq = pirq; -	pirq->irqchip.name = DWAPB_DRIVER_NAME; -	pirq->irqchip.irq_ack = dwapb_irq_ack; -	pirq->irqchip.irq_mask = dwapb_irq_mask; -	pirq->irqchip.irq_unmask = dwapb_irq_unmask; -	pirq->irqchip.irq_set_type = dwapb_irq_set_type; -	pirq->irqchip.irq_enable = dwapb_irq_enable; -	pirq->irqchip.irq_disable = dwapb_irq_disable; -#ifdef CONFIG_PM_SLEEP -	pirq->irqchip.irq_set_wake = dwapb_irq_set_wake; -#endif  	/*  	 * Intel ACPI-based platforms mostly have the DesignWare APB GPIO @@ -475,7 +485,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,  		girq->parent_handler = dwapb_irq_handler;  	} -	girq->chip = &pirq->irqchip; +	gpio_irq_chip_set_chip(girq, &dwapb_irq_chip);  	return; @@ -738,7 +748,7 @@ static int dwapb_gpio_suspend(struct device *dev)  	unsigned long flags;  	int i; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	for (i = 0; i < gpio->nr_ports; i++) {  		unsigned int offset;  		unsigned int idx = gpio->ports[i].idx; @@ -765,7 +775,7 @@ static int dwapb_gpio_suspend(struct device *dev)  			dwapb_write(gpio, GPIO_INTMASK, ~ctx->wake_en);  		}  	} -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks); @@ -785,7 +795,7 @@ static int dwapb_gpio_resume(struct device *dev)  		return err;  	} -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	for (i = 0; i < gpio->nr_ports; i++) {  		unsigned int offset;  		unsigned int idx = gpio->ports[i].idx; @@ -812,7 +822,7 @@ static int dwapb_gpio_resume(struct device *dev)  			dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff);  		}  	} -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c index b90a45c939a4..f422c3e129a0 100644 --- a/drivers/gpio/gpio-ftgpio010.c +++ b/drivers/gpio/gpio-ftgpio010.c @@ -315,8 +315,8 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)  	return 0;  dis_clk: -	if (!IS_ERR(g->clk)) -		clk_disable_unprepare(g->clk); +	clk_disable_unprepare(g->clk); +  	return ret;  } @@ -324,8 +324,8 @@ static int ftgpio_gpio_remove(struct platform_device *pdev)  {  	struct ftgpio_gpio *g = platform_get_drvdata(pdev); -	if (!IS_ERR(g->clk)) -		clk_disable_unprepare(g->clk); +	clk_disable_unprepare(g->clk); +  	return 0;  } diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c index b89b8c5ff1f5..097a06463d01 100644 --- a/drivers/gpio/gpio-gpio-mm.c +++ b/drivers/gpio/gpio-gpio-mm.c @@ -42,7 +42,7 @@ struct gpiomm_gpio {  	unsigned char out_state[6];  	unsigned char control[2];  	spinlock_t lock; -	unsigned int base; +	void __iomem *base;  };  static int gpiomm_gpio_get_direction(struct gpio_chip *chip, @@ -64,7 +64,6 @@ static int gpiomm_gpio_direction_input(struct gpio_chip *chip,  	struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);  	const unsigned int io_port = offset / 8;  	const unsigned int control_port = io_port / 3; -	const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;  	unsigned long flags;  	unsigned int control; @@ -89,7 +88,7 @@ static int gpiomm_gpio_direction_input(struct gpio_chip *chip,  	}  	control = BIT(7) | gpiommgpio->control[control_port]; -	outb(control, control_addr); +	iowrite8(control, gpiommgpio->base + 3 + control_port*4);  	spin_unlock_irqrestore(&gpiommgpio->lock, flags); @@ -103,7 +102,6 @@ static int gpiomm_gpio_direction_output(struct gpio_chip *chip,  	const unsigned int io_port = offset / 8;  	const unsigned int control_port = io_port / 3;  	const unsigned int mask = BIT(offset % 8); -	const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;  	const unsigned int out_port = (io_port > 2) ? io_port + 1 : io_port;  	unsigned long flags;  	unsigned int control; @@ -134,9 +132,9 @@ static int gpiomm_gpio_direction_output(struct gpio_chip *chip,  		gpiommgpio->out_state[io_port] &= ~mask;  	control = BIT(7) | gpiommgpio->control[control_port]; -	outb(control, control_addr); +	iowrite8(control, gpiommgpio->base + 3 + control_port*4); -	outb(gpiommgpio->out_state[io_port], gpiommgpio->base + out_port); +	iowrite8(gpiommgpio->out_state[io_port], gpiommgpio->base + out_port);  	spin_unlock_irqrestore(&gpiommgpio->lock, flags); @@ -160,7 +158,7 @@ static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)  		return -EINVAL;  	} -	port_state = inb(gpiommgpio->base + in_port); +	port_state = ioread8(gpiommgpio->base + in_port);  	spin_unlock_irqrestore(&gpiommgpio->lock, flags); @@ -175,7 +173,7 @@ static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,  	struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);  	unsigned long offset;  	unsigned long gpio_mask; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long port_state;  	/* clear bits array to a clean slate */ @@ -183,7 +181,7 @@ static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,  	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {  		port_addr = gpiommgpio->base + ports[offset / 8]; -		port_state = inb(port_addr) & gpio_mask; +		port_state = ioread8(port_addr) & gpio_mask;  		bitmap_set_value8(bits, port_state, offset);  	} @@ -207,7 +205,7 @@ static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,  	else  		gpiommgpio->out_state[port] &= ~mask; -	outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port); +	iowrite8(gpiommgpio->out_state[port], gpiommgpio->base + out_port);  	spin_unlock_irqrestore(&gpiommgpio->lock, flags);  } @@ -219,7 +217,7 @@ static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,  	unsigned long offset;  	unsigned long gpio_mask;  	size_t index; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long bitmask;  	unsigned long flags; @@ -234,7 +232,7 @@ static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,  		/* update output state data and set device gpio register */  		gpiommgpio->out_state[index] &= ~gpio_mask;  		gpiommgpio->out_state[index] |= bitmask; -		outb(gpiommgpio->out_state[index], port_addr); +		iowrite8(gpiommgpio->out_state[index], port_addr);  		spin_unlock_irqrestore(&gpiommgpio->lock, flags);  	} @@ -268,6 +266,10 @@ static int gpiomm_probe(struct device *dev, unsigned int id)  		return -EBUSY;  	} +	gpiommgpio->base = devm_ioport_map(dev, base[id], GPIOMM_EXTENT); +	if (!gpiommgpio->base) +		return -ENOMEM; +  	gpiommgpio->chip.label = name;  	gpiommgpio->chip.parent = dev;  	gpiommgpio->chip.owner = THIS_MODULE; @@ -281,7 +283,6 @@ static int gpiomm_probe(struct device *dev, unsigned int id)  	gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple;  	gpiommgpio->chip.set = gpiomm_gpio_set;  	gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple; -	gpiommgpio->base = base[id];  	spin_lock_init(&gpiommgpio->lock); @@ -292,14 +293,14 @@ static int gpiomm_probe(struct device *dev, unsigned int id)  	}  	/* initialize all GPIO as output */ -	outb(0x80, base[id] + 3); -	outb(0x00, base[id]); -	outb(0x00, base[id] + 1); -	outb(0x00, base[id] + 2); -	outb(0x80, base[id] + 7); -	outb(0x00, base[id] + 4); -	outb(0x00, base[id] + 5); -	outb(0x00, base[id] + 6); +	iowrite8(0x80, gpiommgpio->base + 3); +	iowrite8(0x00, gpiommgpio->base); +	iowrite8(0x00, gpiommgpio->base + 1); +	iowrite8(0x00, gpiommgpio->base + 2); +	iowrite8(0x80, gpiommgpio->base + 7); +	iowrite8(0x00, gpiommgpio->base + 4); +	iowrite8(0x00, gpiommgpio->base + 5); +	iowrite8(0x00, gpiommgpio->base + 6);  	return 0;  } diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 23d447e17a67..df563616f943 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -145,7 +145,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)  		return -EINVAL;  	} -	spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	ipol = priv->gc.read_reg(priv->regs + GRGPIO_IPOL) & ~mask;  	iedge = priv->gc.read_reg(priv->regs + GRGPIO_IEDGE) & ~mask; @@ -153,7 +153,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)  	priv->gc.write_reg(priv->regs + GRGPIO_IPOL, ipol | pol);  	priv->gc.write_reg(priv->regs + GRGPIO_IEDGE, iedge | edge); -	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  	return 0;  } @@ -164,11 +164,11 @@ static void grgpio_irq_mask(struct irq_data *d)  	int offset = d->hwirq;  	unsigned long flags; -	spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	grgpio_set_imask(priv, offset, 0); -	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  }  static void grgpio_irq_unmask(struct irq_data *d) @@ -177,11 +177,11 @@ static void grgpio_irq_unmask(struct irq_data *d)  	int offset = d->hwirq;  	unsigned long flags; -	spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	grgpio_set_imask(priv, offset, 1); -	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  }  static struct irq_chip grgpio_irq_chip = { @@ -199,7 +199,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)  	int i;  	int match = 0; -	spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	/*  	 * For each gpio line, call its interrupt handler if it its underlying @@ -215,7 +215,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)  		}  	} -	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  	if (!match)  		dev_warn(priv->dev, "No gpio line matched irq %d\n", irq); @@ -247,13 +247,13 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,  	dev_dbg(priv->dev, "Mapping irq %d for gpio line %d\n",  		irq, offset); -	spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	/* Request underlying irq if not already requested */  	lirq->irq = irq;  	uirq = &priv->uirqs[lirq->index];  	if (uirq->refcnt == 0) { -		spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +		raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  		ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,  				  dev_name(priv->dev), priv);  		if (ret) { @@ -262,11 +262,11 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,  				uirq->uirq);  			return ret;  		} -		spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +		raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	}  	uirq->refcnt++; -	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  	/* Setup irq  */  	irq_set_chip_data(irq, priv); @@ -290,7 +290,7 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)  	irq_set_chip_and_handler(irq, NULL, NULL);  	irq_set_chip_data(irq, NULL); -	spin_lock_irqsave(&priv->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);  	/* Free underlying irq if last user unmapped */  	index = -1; @@ -309,13 +309,13 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)  		uirq = &priv->uirqs[lirq->index];  		uirq->refcnt--;  		if (uirq->refcnt == 0) { -			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +			raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  			free_irq(uirq->uirq, priv);  			return;  		}  	} -	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);  }  static const struct irq_domain_ops grgpio_irq_domain_ops = { diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c index 641719a96a1a..4e13e937f832 100644 --- a/drivers/gpio/gpio-hlwd.c +++ b/drivers/gpio/gpio-hlwd.c @@ -65,7 +65,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)  	int hwirq;  	u32 emulated_pending; -	spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);  	pending = ioread32be(hlwd->regs + HW_GPIOB_INTFLAG);  	pending &= ioread32be(hlwd->regs + HW_GPIOB_INTMASK); @@ -93,7 +93,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)  		/* Mark emulated interrupts as pending */  		pending |= rising | falling;  	} -	spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);  	chained_irq_enter(chip, desc); @@ -118,11 +118,11 @@ static void hlwd_gpio_irq_mask(struct irq_data *data)  	unsigned long flags;  	u32 mask; -	spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);  	mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);  	mask &= ~BIT(data->hwirq);  	iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK); -	spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);  }  static void hlwd_gpio_irq_unmask(struct irq_data *data) @@ -132,11 +132,11 @@ static void hlwd_gpio_irq_unmask(struct irq_data *data)  	unsigned long flags;  	u32 mask; -	spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);  	mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);  	mask |= BIT(data->hwirq);  	iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK); -	spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);  }  static void hlwd_gpio_irq_enable(struct irq_data *data) @@ -173,7 +173,7 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)  	unsigned long flags;  	u32 level; -	spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);  	hlwd->edge_emulation &= ~BIT(data->hwirq); @@ -194,11 +194,11 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)  		hlwd_gpio_irq_setup_emulation(hlwd, data->hwirq, flow_type);  		break;  	default: -		spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags); +		raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);  		return -EINVAL;  	} -	spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);  	return 0;  } diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c index 52b8b72ded77..1cafdf46f875 100644 --- a/drivers/gpio/gpio-idt3243x.c +++ b/drivers/gpio/gpio-idt3243x.c @@ -57,7 +57,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)  	if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))  		return -EINVAL; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);  	if (sense & IRQ_TYPE_LEVEL_HIGH) @@ -68,7 +68,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)  	writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);  	irq_set_handler_locked(d, handle_level_irq); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } @@ -86,12 +86,12 @@ static void idt_gpio_mask(struct irq_data *d)  	struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	ctrl->mask_cache |= BIT(d->hwirq);  	writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void idt_gpio_unmask(struct irq_data *d) @@ -100,12 +100,12 @@ static void idt_gpio_unmask(struct irq_data *d)  	struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	ctrl->mask_cache &= ~BIT(d->hwirq);  	writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static int idt_gpio_irq_init_hw(struct gpio_chip *gc) diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c index b3b050604e0b..312309be0287 100644 --- a/drivers/gpio/gpio-ixp4xx.c +++ b/drivers/gpio/gpio-ixp4xx.c @@ -14,10 +14,6 @@  #include <linux/of_irq.h>  #include <linux/platform_device.h>  #include <linux/bitops.h> -/* Include that go away with DT transition */ -#include <linux/irqchip/irq-ixp4xx.h> - -#include <asm/mach-types.h>  #define IXP4XX_REG_GPOUT	0x00  #define IXP4XX_REG_GPOE		0x04 @@ -128,7 +124,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)  		int_reg = IXP4XX_REG_GPIT1;  	} -	spin_lock_irqsave(&g->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&g->gc.bgpio_lock, flags);  	/* Clear the style for the appropriate pin */  	val = __raw_readl(g->base + int_reg); @@ -147,7 +143,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)  	val |= BIT(d->hwirq);  	__raw_writel(val, g->base + IXP4XX_REG_GPOE); -	spin_unlock_irqrestore(&g->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);  	/* This parent only accept level high (asserted) */  	return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); @@ -195,6 +191,7 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)  	struct resource *res;  	struct ixp4xx_gpio *g;  	struct gpio_irq_chip *girq; +	struct device_node *irq_parent;  	int ret;  	g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); @@ -207,40 +204,24 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)  	if (IS_ERR(g->base))  		return PTR_ERR(g->base); -	/* -	 * When we convert to device tree we will simply look up the -	 * parent irqdomain using irq_find_host(parent) as parent comes -	 * from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get -	 * the fwnode. For now we need this boardfile style code. -	 */ -	if (np) { -		struct device_node *irq_parent; - -		irq_parent = of_irq_find_parent(np); -		if (!irq_parent) { -			dev_err(dev, "no IRQ parent node\n"); -			return -ENODEV; -		} -		parent = irq_find_host(irq_parent); -		if (!parent) { -			dev_err(dev, "no IRQ parent domain\n"); -			return -ENODEV; -		} -		g->fwnode = of_node_to_fwnode(np); -	} else { -		parent = ixp4xx_get_irq_domain(); -		g->fwnode = irq_domain_alloc_fwnode(&res->start); -		if (!g->fwnode) { -			dev_err(dev, "no domain base\n"); -			return -ENODEV; -		} +	irq_parent = of_irq_find_parent(np); +	if (!irq_parent) { +		dev_err(dev, "no IRQ parent node\n"); +		return -ENODEV; +	} +	parent = irq_find_host(irq_parent); +	if (!parent) { +		dev_err(dev, "no IRQ parent domain\n"); +		return -ENODEV;  	} +	g->fwnode = of_node_to_fwnode(np);  	/*  	 * Make sure GPIO 14 and 15 are NOT used as clocks but GPIO on  	 * specific machines.  	 */ -	if (machine_is_dsmg600() || machine_is_nas100d()) +	if (of_machine_is_compatible("dlink,dsm-g600-a") || +	    of_machine_is_compatible("iom,nas-100d"))  		__raw_writel(0x0, g->base + IXP4XX_REG_GPCLK);  	/* diff --git a/drivers/gpio/gpio-loongson1.c b/drivers/gpio/gpio-loongson1.c index 1b1ee94eeab4..5d90b3bc5a25 100644 --- a/drivers/gpio/gpio-loongson1.c +++ b/drivers/gpio/gpio-loongson1.c @@ -25,10 +25,10 @@ static int ls1x_gpio_request(struct gpio_chip *gc, unsigned int offset)  {  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	__raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) | BIT(offset),  		     gpio_reg_base + GPIO_CFG); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } @@ -37,10 +37,10 @@ static void ls1x_gpio_free(struct gpio_chip *gc, unsigned int offset)  {  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	__raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) & ~BIT(offset),  		     gpio_reg_base + GPIO_CFG); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static int ls1x_gpio_probe(struct platform_device *pdev) diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 238cbe926b9f..da6972117030 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -496,17 +496,13 @@ static int max732x_irq_setup(struct max732x_chip *chip,  			     const struct i2c_device_id *id)  {  	struct i2c_client *client = chip->client; -	struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);  	int has_irq = max732x_features[id->driver_data] >> 32;  	int irq_base = 0;  	int ret; -	if (((pdata && pdata->irq_base) || client->irq) -			&& has_irq != INT_NONE) { +	if (client->irq && has_irq != INT_NONE) {  		struct gpio_irq_chip *girq; -		if (pdata) -			irq_base = pdata->irq_base;  		chip->irq_features = has_irq;  		mutex_init(&chip->irq_lock); @@ -540,10 +536,9 @@ static int max732x_irq_setup(struct max732x_chip *chip,  			     const struct i2c_device_id *id)  {  	struct i2c_client *client = chip->client; -	struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);  	int has_irq = max732x_features[id->driver_data] >> 32; -	if (((pdata && pdata->irq_base) || client->irq) && has_irq != INT_NONE) +	if (client->irq && has_irq != INT_NONE)  		dev_warn(&client->dev, "interrupt support not compiled in\n");  	return 0; @@ -703,44 +698,16 @@ static int max732x_probe(struct i2c_client *client,  	if (ret)  		return ret; -	if (pdata->setup) { -		ret = pdata->setup(client, chip->gpio_chip.base, -				chip->gpio_chip.ngpio, pdata->context); -		if (ret < 0) -			dev_warn(&client->dev, "setup failed, %d\n", ret); -	} -  	i2c_set_clientdata(client, chip);  	return 0;  } -static int max732x_remove(struct i2c_client *client) -{ -	struct max732x_platform_data *pdata = dev_get_platdata(&client->dev); -	struct max732x_chip *chip = i2c_get_clientdata(client); - -	if (pdata && pdata->teardown) { -		int ret; - -		ret = pdata->teardown(client, chip->gpio_chip.base, -				chip->gpio_chip.ngpio, pdata->context); -		if (ret < 0) { -			dev_err(&client->dev, "%s failed, %d\n", -					"teardown", ret); -			return ret; -		} -	} - -	return 0; -} -  static struct i2c_driver max732x_driver = {  	.driver = {  		.name		= "max732x",  		.of_match_table	= of_match_ptr(max732x_of_table),  	},  	.probe		= max732x_probe, -	.remove		= max732x_remove,  	.id_table	= max732x_id,  }; diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c index ebf9dea6546b..c18b60e39a94 100644 --- a/drivers/gpio/gpio-max77620.c +++ b/drivers/gpio/gpio-max77620.c @@ -54,6 +54,7 @@ static void max77620_gpio_irq_mask(struct irq_data *data)  	struct max77620_gpio *gpio = gpiochip_get_data(chip);  	gpio->irq_enabled[data->hwirq] = false; +	gpiochip_disable_irq(chip, data->hwirq);  }  static void max77620_gpio_irq_unmask(struct irq_data *data) @@ -61,6 +62,7 @@ static void max77620_gpio_irq_unmask(struct irq_data *data)  	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);  	struct max77620_gpio *gpio = gpiochip_get_data(chip); +	gpiochip_enable_irq(chip, data->hwirq);  	gpio->irq_enabled[data->hwirq] = true;  } @@ -119,14 +121,15 @@ static void max77620_gpio_bus_sync_unlock(struct irq_data *data)  	mutex_unlock(&gpio->buslock);  } -static struct irq_chip max77620_gpio_irqchip = { +static const struct irq_chip max77620_gpio_irqchip = {  	.name		= "max77620-gpio",  	.irq_mask	= max77620_gpio_irq_mask,  	.irq_unmask	= max77620_gpio_irq_unmask,  	.irq_set_type	= max77620_gpio_set_irq_type,  	.irq_bus_lock	= max77620_gpio_bus_lock,  	.irq_bus_sync_unlock = max77620_gpio_bus_sync_unlock, -	.flags		= IRQCHIP_MASK_ON_SUSPEND, +	.flags		= IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND, +	GPIOCHIP_IRQ_RESOURCE_HELPERS,  };  static int max77620_gpio_dir_input(struct gpio_chip *gc, unsigned int offset) @@ -318,7 +321,7 @@ static int max77620_gpio_probe(struct platform_device *pdev)  	mgpio->gpio_chip.base = -1;  	girq = &mgpio->gpio_chip.irq; -	girq->chip = &max77620_gpio_irqchip; +	gpio_irq_chip_set_chip(girq, &max77620_gpio_irqchip);  	/* This will let us handle the parent IRQ in the driver */  	girq->parent_handler = NULL;  	girq->num_parents = 0; diff --git a/drivers/gpio/gpio-menz127.c b/drivers/gpio/gpio-menz127.c index 1e21c661d79d..a035a9bcb57c 100644 --- a/drivers/gpio/gpio-menz127.c +++ b/drivers/gpio/gpio-menz127.c @@ -64,7 +64,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,  		debounce /= 50;  	} -	spin_lock(&gc->bgpio_lock); +	raw_spin_lock(&gc->bgpio_lock);  	db_en = readl(priv->reg_base + MEN_Z127_DBER); @@ -79,7 +79,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,  	writel(db_en, priv->reg_base + MEN_Z127_DBER);  	writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio)); -	spin_unlock(&gc->bgpio_lock); +	raw_spin_unlock(&gc->bgpio_lock);  	return 0;  } @@ -91,7 +91,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,  	struct men_z127_gpio *priv = gpiochip_get_data(gc);  	u32 od_en; -	spin_lock(&gc->bgpio_lock); +	raw_spin_lock(&gc->bgpio_lock);  	od_en = readl(priv->reg_base + MEN_Z127_ODER);  	if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN) @@ -101,7 +101,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,  		od_en &= ~BIT(offset);  	writel(od_en, priv->reg_base + MEN_Z127_ODER); -	spin_unlock(&gc->bgpio_lock); +	raw_spin_unlock(&gc->bgpio_lock);  	return 0;  } diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index b060c4773698..48e3768a830e 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -409,29 +409,27 @@ static int ioh_gpio_probe(struct pci_dev *pdev,  	void *chip_save;  	int irq_base; -	ret = pci_enable_device(pdev); +	ret = pcim_enable_device(pdev);  	if (ret) { -		dev_err(dev, "%s : pci_enable_device failed", __func__); -		goto err_pci_enable; +		dev_err(dev, "%s : pcim_enable_device failed", __func__); +		return ret;  	} -	ret = pci_request_regions(pdev, KBUILD_MODNAME); +	ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME);  	if (ret) { -		dev_err(dev, "pci_request_regions failed-%d", ret); -		goto err_request_regions; +		dev_err(dev, "pcim_iomap_regions failed-%d", ret); +		return ret;  	} -	base = pci_iomap(pdev, 1, 0); +	base = pcim_iomap_table(pdev)[1];  	if (!base) { -		dev_err(dev, "%s : pci_iomap failed", __func__); -		ret = -ENOMEM; -		goto err_iomap; +		dev_err(dev, "%s : pcim_iomap_table failed", __func__); +		return -ENOMEM;  	} -	chip_save = kcalloc(8, sizeof(*chip), GFP_KERNEL); +	chip_save = devm_kcalloc(dev, 8, sizeof(*chip), GFP_KERNEL);  	if (chip_save == NULL) { -		ret = -ENOMEM; -		goto err_kzalloc; +		return -ENOMEM;  	}  	chip = chip_save; @@ -442,10 +440,10 @@ static int ioh_gpio_probe(struct pci_dev *pdev,  		chip->ch = i;  		spin_lock_init(&chip->spinlock);  		ioh_gpio_setup(chip, num_ports[i]); -		ret = gpiochip_add_data(&chip->gpio, chip); +		ret = devm_gpiochip_add_data(dev, &chip->gpio, chip);  		if (ret) {  			dev_err(dev, "IOH gpio: Failed to register GPIO\n"); -			goto err_gpiochip_add; +			return ret;  		}  	} @@ -456,15 +454,14 @@ static int ioh_gpio_probe(struct pci_dev *pdev,  		if (irq_base < 0) {  			dev_warn(dev,  				"ml_ioh_gpio: Failed to get IRQ base num\n"); -			ret = irq_base; -			goto err_gpiochip_add; +			return irq_base;  		}  		chip->irq_base = irq_base;  		ret = ioh_gpio_alloc_generic_chip(chip,  						  irq_base, num_ports[j]);  		if (ret) -			goto err_gpiochip_add; +			return ret;  	}  	chip = chip_save; @@ -472,52 +469,12 @@ static int ioh_gpio_probe(struct pci_dev *pdev,  			       IRQF_SHARED, KBUILD_MODNAME, chip);  	if (ret != 0) {  		dev_err(dev, "%s request_irq failed\n", __func__); -		goto err_gpiochip_add; +		return ret;  	}  	pci_set_drvdata(pdev, chip);  	return 0; - -err_gpiochip_add: -	chip = chip_save; -	while (--i >= 0) { -		gpiochip_remove(&chip->gpio); -		chip++; -	} -	kfree(chip_save); - -err_kzalloc: -	pci_iounmap(pdev, base); - -err_iomap: -	pci_release_regions(pdev); - -err_request_regions: -	pci_disable_device(pdev); - -err_pci_enable: - -	dev_err(dev, "%s Failed returns %d\n", __func__, ret); -	return ret; -} - -static void ioh_gpio_remove(struct pci_dev *pdev) -{ -	int i; -	struct ioh_gpio *chip = pci_get_drvdata(pdev); -	void *chip_save; - -	chip_save = chip; - -	for (i = 0; i < 8; i++, chip++) -		gpiochip_remove(&chip->gpio); - -	chip = chip_save; -	pci_iounmap(pdev, chip->base); -	pci_release_regions(pdev); -	pci_disable_device(pdev); -	kfree(chip);  }  static int __maybe_unused ioh_gpio_suspend(struct device *dev) @@ -558,7 +515,6 @@ static struct pci_driver ioh_gpio_driver = {  	.name = "ml_ioh_gpio",  	.id_table = ioh_gpio_pcidev_id,  	.probe = ioh_gpio_probe, -	.remove = ioh_gpio_remove,  	.driver = {  		.pm = &ioh_gpio_pm_ops,  	}, diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c index 3d89912a05b8..64cb060d9d75 100644 --- a/drivers/gpio/gpio-mlxbf2.c +++ b/drivers/gpio/gpio-mlxbf2.c @@ -131,7 +131,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)  	u32 arm_gpio_lock_val;  	mutex_lock(yu_arm_gpio_lock_param.lock); -	spin_lock(&gs->gc.bgpio_lock); +	raw_spin_lock(&gs->gc.bgpio_lock);  	arm_gpio_lock_val = readl(yu_arm_gpio_lock_param.io); @@ -139,7 +139,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)  	 * When lock active bit[31] is set, ModeX is write enabled  	 */  	if (YU_LOCK_ACTIVE_BIT(arm_gpio_lock_val)) { -		spin_unlock(&gs->gc.bgpio_lock); +		raw_spin_unlock(&gs->gc.bgpio_lock);  		mutex_unlock(yu_arm_gpio_lock_param.lock);  		return -EINVAL;  	} @@ -157,7 +157,7 @@ static void mlxbf2_gpio_lock_release(struct mlxbf2_gpio_context *gs)  	__releases(yu_arm_gpio_lock_param.lock)  {  	writel(YU_ARM_GPIO_LOCK_RELEASE, yu_arm_gpio_lock_param.io); -	spin_unlock(&gs->gc.bgpio_lock); +	raw_spin_unlock(&gs->gc.bgpio_lock);  	mutex_unlock(yu_arm_gpio_lock_param.lock);  } @@ -237,7 +237,7 @@ static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)  	unsigned long flags;  	u32 val; -	spin_lock_irqsave(&gs->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);  	val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);  	val |= BIT(offset);  	writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE); @@ -245,7 +245,7 @@ static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)  	val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);  	val |= BIT(offset);  	writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0); -	spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);  }  static void mlxbf2_gpio_irq_disable(struct irq_data *irqd) @@ -256,11 +256,11 @@ static void mlxbf2_gpio_irq_disable(struct irq_data *irqd)  	unsigned long flags;  	u32 val; -	spin_lock_irqsave(&gs->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);  	val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);  	val &= ~BIT(offset);  	writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0); -	spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);  }  static irqreturn_t mlxbf2_gpio_irq_handler(int irq, void *ptr) @@ -307,7 +307,7 @@ mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)  		return -EINVAL;  	} -	spin_lock_irqsave(&gs->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);  	if (fall) {  		val = readl(gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);  		val |= BIT(offset); @@ -319,7 +319,7 @@ mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)  		val |= BIT(offset);  		writel(val, gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);  	} -	spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);  	return 0;  } diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index c335a0309ba3..d9dff3dc92ae 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -220,7 +220,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)  	unsigned long mask = bgpio_line2mask(gc, gpio);  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	if (val)  		gc->bgpio_data |= mask; @@ -229,7 +229,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)  	gc->write_reg(gc->reg_dat, gc->bgpio_data); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, @@ -248,7 +248,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)  	unsigned long mask = bgpio_line2mask(gc, gpio);  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	if (val)  		gc->bgpio_data |= mask; @@ -257,7 +257,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)  	gc->write_reg(gc->reg_set, gc->bgpio_data); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void bgpio_multiple_get_masks(struct gpio_chip *gc, @@ -286,7 +286,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,  	unsigned long flags;  	unsigned long set_mask, clear_mask; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask); @@ -295,7 +295,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,  	gc->write_reg(reg, gc->bgpio_data); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, @@ -347,7 +347,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)  {  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); @@ -356,7 +356,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)  	if (gc->reg_dir_out)  		gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	return 0;  } @@ -387,7 +387,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)  {  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	gc->bgpio_dir |= bgpio_line2mask(gc, gpio); @@ -396,7 +396,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)  	if (gc->reg_dir_out)  		gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  }  static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio, @@ -610,7 +610,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,  	if (gc->bgpio_bits > BITS_PER_LONG)  		return -EINVAL; -	spin_lock_init(&gc->bgpio_lock); +	raw_spin_lock_init(&gc->bgpio_lock);  	gc->parent = dev;  	gc->label = dev_name(dev);  	gc->base = -1; diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 8726921a1129..b444c6ab958b 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -71,6 +71,7 @@  #define PCA_CHIP_TYPE(x)	((x) & PCA_TYPE_MASK)  static const struct i2c_device_id pca953x_id[] = { +	{ "pca6408", 8  | PCA953X_TYPE | PCA_INT, },  	{ "pca6416", 16 | PCA953X_TYPE | PCA_INT, },  	{ "pca9505", 40 | PCA953X_TYPE | PCA_INT, },  	{ "pca9506", 40 | PCA953X_TYPE | PCA_INT, }, @@ -200,7 +201,6 @@ struct pca953x_chip {  	DECLARE_BITMAP(irq_stat, MAX_LINE);  	DECLARE_BITMAP(irq_trig_raise, MAX_LINE);  	DECLARE_BITMAP(irq_trig_fall, MAX_LINE); -	struct irq_chip irq_chip;  #endif  	atomic_t wakeup_path; @@ -628,6 +628,7 @@ static void pca953x_irq_mask(struct irq_data *d)  	irq_hw_number_t hwirq = irqd_to_hwirq(d);  	clear_bit(hwirq, chip->irq_mask); +	gpiochip_disable_irq(gc, hwirq);  }  static void pca953x_irq_unmask(struct irq_data *d) @@ -636,6 +637,7 @@ static void pca953x_irq_unmask(struct irq_data *d)  	struct pca953x_chip *chip = gpiochip_get_data(gc);  	irq_hw_number_t hwirq = irqd_to_hwirq(d); +	gpiochip_enable_irq(gc, hwirq);  	set_bit(hwirq, chip->irq_mask);  } @@ -720,6 +722,26 @@ static void pca953x_irq_shutdown(struct irq_data *d)  	clear_bit(hwirq, chip->irq_trig_fall);  } +static void pca953x_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 pca953x_irq_chip = { +	.irq_mask		= pca953x_irq_mask, +	.irq_unmask		= pca953x_irq_unmask, +	.irq_set_wake		= pca953x_irq_set_wake, +	.irq_bus_lock		= pca953x_irq_bus_lock, +	.irq_bus_sync_unlock	= pca953x_irq_bus_sync_unlock, +	.irq_set_type		= pca953x_irq_set_type, +	.irq_shutdown		= pca953x_irq_shutdown, +	.irq_print_chip		= pca953x_irq_print_chip, +	.flags			= IRQCHIP_IMMUTABLE, +	GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; +  static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending)  {  	struct gpio_chip *gc = &chip->gpio_chip; @@ -811,7 +833,6 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)  static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)  {  	struct i2c_client *client = chip->client; -	struct irq_chip *irq_chip = &chip->irq_chip;  	DECLARE_BITMAP(reg_direction, MAX_LINE);  	DECLARE_BITMAP(irq_stat, MAX_LINE);  	struct gpio_irq_chip *girq; @@ -845,17 +866,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)  	bitmap_and(chip->irq_stat, irq_stat, reg_direction, chip->gpio_chip.ngpio);  	mutex_init(&chip->irq_lock); -	irq_chip->name = dev_name(&client->dev); -	irq_chip->irq_mask = pca953x_irq_mask; -	irq_chip->irq_unmask = pca953x_irq_unmask; -	irq_chip->irq_set_wake = pca953x_irq_set_wake; -	irq_chip->irq_bus_lock = pca953x_irq_bus_lock; -	irq_chip->irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock; -	irq_chip->irq_set_type = pca953x_irq_set_type; -	irq_chip->irq_shutdown = pca953x_irq_shutdown; -  	girq = &chip->gpio_chip.irq; -	girq->chip = irq_chip; +	gpio_irq_chip_set_chip(girq, &pca953x_irq_chip);  	/* This will let us handle the parent IRQ in the driver */  	girq->parent_handler = NULL;  	girq->num_parents = 0; @@ -1198,6 +1210,7 @@ static int pca953x_resume(struct device *dev)  #define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int)  static const struct of_device_id pca953x_dt_ids[] = { +	{ .compatible = "nxp,pca6408", .data = OF_953X(8, PCA_INT), },  	{ .compatible = "nxp,pca6416", .data = OF_953X(16, PCA_INT), },  	{ .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },  	{ .compatible = "nxp,pca9506", .data = OF_953X(40, PCA_INT), }, diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index b7568ee33696..59cc27e4de51 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -71,7 +71,6 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table);   */  struct pcf857x {  	struct gpio_chip	chip; -	struct irq_chip		irqchip;  	struct i2c_client	*client;  	struct mutex		lock;		/* protect 'out' */  	unsigned		out;		/* software latch */ @@ -203,15 +202,19 @@ static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on)  static void pcf857x_irq_enable(struct irq_data *data)  {  	struct pcf857x *gpio = irq_data_get_irq_chip_data(data); +	irq_hw_number_t hwirq = irqd_to_hwirq(data); -	gpio->irq_enabled |= (1 << data->hwirq); +	gpiochip_enable_irq(&gpio->chip, hwirq); +	gpio->irq_enabled |= (1 << hwirq);  }  static void pcf857x_irq_disable(struct irq_data *data)  {  	struct pcf857x *gpio = irq_data_get_irq_chip_data(data); +	irq_hw_number_t hwirq = irqd_to_hwirq(data); -	gpio->irq_enabled &= ~(1 << data->hwirq); +	gpio->irq_enabled &= ~(1 << hwirq); +	gpiochip_disable_irq(&gpio->chip, hwirq);  }  static void pcf857x_irq_bus_lock(struct irq_data *data) @@ -228,6 +231,20 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)  	mutex_unlock(&gpio->lock);  } +static const struct irq_chip pcf857x_irq_chip = { +	.name			= "pcf857x", +	.irq_enable		= pcf857x_irq_enable, +	.irq_disable		= pcf857x_irq_disable, +	.irq_ack		= noop, +	.irq_mask		= noop, +	.irq_unmask		= noop, +	.irq_set_wake		= pcf857x_irq_set_wake, +	.irq_bus_lock		= pcf857x_irq_bus_lock, +	.irq_bus_sync_unlock	= pcf857x_irq_bus_sync_unlock, +	.flags			= IRQCHIP_IMMUTABLE, +	GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; +  /*-------------------------------------------------------------------------*/  static int pcf857x_probe(struct i2c_client *client, @@ -338,16 +355,6 @@ static int pcf857x_probe(struct i2c_client *client,  	if (client->irq) {  		struct gpio_irq_chip *girq; -		gpio->irqchip.name = "pcf857x"; -		gpio->irqchip.irq_enable = pcf857x_irq_enable; -		gpio->irqchip.irq_disable = pcf857x_irq_disable; -		gpio->irqchip.irq_ack = noop; -		gpio->irqchip.irq_mask = noop; -		gpio->irqchip.irq_unmask = noop; -		gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake; -		gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock; -		gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock; -  		status = devm_request_threaded_irq(&client->dev, client->irq,  					NULL, pcf857x_irq, IRQF_ONESHOT |  					IRQF_TRIGGER_FALLING | IRQF_SHARED, @@ -356,7 +363,7 @@ static int pcf857x_probe(struct i2c_client *client,  			goto fail;  		girq = &gpio->chip.irq; -		girq->chip = &gpio->irqchip; +		gpio_irq_chip_set_chip(girq, &pcf857x_irq_chip);  		/* This will let us handle the parent IRQ in the driver */  		girq->parent_handler = NULL;  		girq->num_parents = 0; @@ -396,20 +403,12 @@ static int pcf857x_remove(struct i2c_client *client)  {  	struct pcf857x_platform_data	*pdata = dev_get_platdata(&client->dev);  	struct pcf857x			*gpio = i2c_get_clientdata(client); -	int				status = 0; -	if (pdata && pdata->teardown) { -		status = pdata->teardown(client, -				gpio->chip.base, gpio->chip.ngpio, +	if (pdata && pdata->teardown) +		pdata->teardown(client, gpio->chip.base, gpio->chip.ngpio,  				pdata->context); -		if (status < 0) { -			dev_err(&client->dev, "%s --> %d\n", -					"teardown", status); -			return status; -		} -	} -	return status; +	return 0;  }  static void pcf857x_shutdown(struct i2c_client *client) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 3a76538f27fa..5b117f3bd322 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -44,7 +44,6 @@ struct gpio_rcar_priv {  	spinlock_t lock;  	struct device *dev;  	struct gpio_chip gpio_chip; -	struct irq_chip irq_chip;  	unsigned int irq_parent;  	atomic_t wakeup_path;  	struct gpio_rcar_info info; @@ -96,16 +95,20 @@ static void gpio_rcar_irq_disable(struct irq_data *d)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);  	struct gpio_rcar_priv *p = gpiochip_get_data(gc); +	irq_hw_number_t hwirq = irqd_to_hwirq(d); -	gpio_rcar_write(p, INTMSK, ~BIT(irqd_to_hwirq(d))); +	gpio_rcar_write(p, INTMSK, ~BIT(hwirq)); +	gpiochip_disable_irq(gc, hwirq);  }  static void gpio_rcar_irq_enable(struct irq_data *d)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);  	struct gpio_rcar_priv *p = gpiochip_get_data(gc); +	irq_hw_number_t hwirq = irqd_to_hwirq(d); -	gpio_rcar_write(p, MSKCLR, BIT(irqd_to_hwirq(d))); +	gpiochip_enable_irq(gc, hwirq); +	gpio_rcar_write(p, MSKCLR, BIT(hwirq));  }  static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p, @@ -203,6 +206,17 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)  	return 0;  } +static const struct irq_chip gpio_rcar_irq_chip = { +	.name		= "gpio-rcar", +	.irq_mask	= gpio_rcar_irq_disable, +	.irq_unmask	= gpio_rcar_irq_enable, +	.irq_set_type	= gpio_rcar_irq_set_type, +	.irq_set_wake	= gpio_rcar_irq_set_wake, +	.flags		= IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED | +			  IRQCHIP_MASK_ON_SUSPEND, +	GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; +  static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)  {  	struct gpio_rcar_priv *p = dev_id; @@ -411,7 +425,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen3 = {  	.has_inen = false,  }; -static const struct gpio_rcar_info gpio_rcar_info_v3u = { +static const struct gpio_rcar_info gpio_rcar_info_gen4 = {  	.has_outdtsel = true,  	.has_both_edge_trigger = true,  	.has_always_in = true, @@ -421,7 +435,7 @@ static const struct gpio_rcar_info gpio_rcar_info_v3u = {  static const struct of_device_id gpio_rcar_of_table[] = {  	{  		.compatible = "renesas,gpio-r8a779a0", -		.data = &gpio_rcar_info_v3u, +		.data = &gpio_rcar_info_gen4,  	}, {  		.compatible = "renesas,rcar-gen1-gpio",  		.data = &gpio_rcar_info_gen1, @@ -432,6 +446,9 @@ static const struct of_device_id gpio_rcar_of_table[] = {  		.compatible = "renesas,rcar-gen3-gpio",  		.data = &gpio_rcar_info_gen3,  	}, { +		.compatible = "renesas,rcar-gen4-gpio", +		.data = &gpio_rcar_info_gen4, +	}, {  		.compatible = "renesas,gpio-rcar",  		.data = &gpio_rcar_info_gen1,  	}, { @@ -478,7 +495,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)  {  	struct gpio_rcar_priv *p;  	struct gpio_chip *gpio_chip; -	struct irq_chip *irq_chip;  	struct gpio_irq_chip *girq;  	struct device *dev = &pdev->dev;  	const char *name = dev_name(dev); @@ -528,16 +544,8 @@ static int gpio_rcar_probe(struct platform_device *pdev)  	gpio_chip->base = -1;  	gpio_chip->ngpio = npins; -	irq_chip = &p->irq_chip; -	irq_chip->name = "gpio-rcar"; -	irq_chip->irq_mask = gpio_rcar_irq_disable; -	irq_chip->irq_unmask = gpio_rcar_irq_enable; -	irq_chip->irq_set_type = gpio_rcar_irq_set_type; -	irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; -	irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; -  	girq = &gpio_chip->irq; -	girq->chip = irq_chip; +	gpio_irq_chip_set_chip(girq, &gpio_rcar_irq_chip);  	/* This will let us handle the parent IRQ in the driver */  	girq->parent_handler = NULL;  	girq->num_parents = 0; diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c index bd75401b549d..c52b2cb1acae 100644 --- a/drivers/gpio/gpio-realtek-otto.c +++ b/drivers/gpio/gpio-realtek-otto.c @@ -1,6 +1,7 @@  // SPDX-License-Identifier: GPL-2.0-only  #include <linux/gpio/driver.h> +#include <linux/cpumask.h>  #include <linux/irq.h>  #include <linux/minmax.h>  #include <linux/mod_devicetable.h> @@ -55,9 +56,13 @@  struct realtek_gpio_ctrl {  	struct gpio_chip gc;  	void __iomem *base; +	void __iomem *cpumask_base; +	struct cpumask cpu_irq_maskable;  	raw_spinlock_t lock;  	u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];  	u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK]; +	unsigned int (*port_offset_u8)(unsigned int port); +	unsigned int (*port_offset_u16)(unsigned int port);  };  /* Expand with more flags as devices with other quirks are added */ @@ -69,6 +74,16 @@ enum realtek_gpio_flags {  	 * line the IRQ handler was assigned to, causing uncaught interrupts.  	 */  	GPIO_INTERRUPTS_DISABLED = BIT(0), +	/* +	 * Port order is reversed, meaning DCBA register layout for 1-bit +	 * fields, and [BA, DC] for 2-bit fields. +	 */ +	GPIO_PORTS_REVERSED = BIT(1), +	/* +	 * Interrupts can be enabled per cpu. This requires a secondary IO +	 * range, where the per-cpu enable masks are located. +	 */ +	GPIO_INTERRUPTS_PER_CPU = BIT(2),  };  static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data) @@ -86,21 +101,50 @@ static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)   * port. The two interrupt mask registers store two bits per GPIO, so use u16   * values.   */ +static unsigned int realtek_gpio_port_offset_u8(unsigned int port) +{ +	return port; +} + +static unsigned int realtek_gpio_port_offset_u16(unsigned int port) +{ +	return 2 * port; +} + +/* + * Reversed port order register access + * + * For registers with one bit per GPIO, all ports are stored as u8-s in one + * register in reversed order. The two interrupt mask registers store two bits + * per GPIO, so use u16 values. The first register contains ports 1 and 0, the + * second ports 3 and 2. + */ +static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port) +{ +	return 3 - port; +} + +static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port) +{ +	return 2 * (port ^ 1); +} +  static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl,  	unsigned int port, u16 irq_type, u16 irq_mask)  { -	iowrite16(irq_type & irq_mask, ctrl->base + REALTEK_GPIO_REG_IMR + 2 * port); +	iowrite16(irq_type & irq_mask, +		ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port));  }  static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl,  	unsigned int port, u8 mask)  { -	iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + port); +	iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));  }  static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port)  { -	return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + port); +	return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));  }  /* Set the rising and falling edge mask bits for a GPIO port pin */ @@ -211,14 +255,61 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc)  	chained_irq_exit(irq_chip, desc);  } +static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, +	unsigned int port, int cpu) +{ +	return ctrl->cpumask_base + ctrl->port_offset_u8(port) + +		REALTEK_GPIO_PORTS_PER_BANK * cpu; +} + +static int realtek_gpio_irq_set_affinity(struct irq_data *data, +	const struct cpumask *dest, bool force) +{ +	struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); +	unsigned int line = irqd_to_hwirq(data); +	unsigned int port = line / 8; +	unsigned int port_pin = line % 8; +	void __iomem *irq_cpu_mask; +	unsigned long flags; +	int cpu; +	u8 v; + +	if (!ctrl->cpumask_base) +		return -ENXIO; + +	raw_spin_lock_irqsave(&ctrl->lock, flags); + +	for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { +		irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu); +		v = ioread8(irq_cpu_mask); + +		if (cpumask_test_cpu(cpu, dest)) +			v |= BIT(port_pin); +		else +			v &= ~BIT(port_pin); + +		iowrite8(v, irq_cpu_mask); +	} + +	raw_spin_unlock_irqrestore(&ctrl->lock, flags); + +	irq_data_update_effective_affinity(data, dest); + +	return 0; +} +  static int realtek_gpio_irq_init(struct gpio_chip *gc)  {  	struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);  	unsigned int port; +	int cpu;  	for (port = 0; (port * 8) < gc->ngpio; port++) {  		realtek_gpio_write_imr(ctrl, port, 0, 0);  		realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0)); + +		for_each_cpu(cpu, &ctrl->cpu_irq_maskable) +			iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu));  	}  	return 0; @@ -230,6 +321,7 @@ static struct irq_chip realtek_gpio_irq_chip = {  	.irq_mask = realtek_gpio_irq_mask,  	.irq_unmask = realtek_gpio_irq_unmask,  	.irq_set_type = realtek_gpio_irq_set_type, +	.irq_set_affinity = realtek_gpio_irq_set_affinity,  };  static const struct of_device_id realtek_gpio_of_match[] = { @@ -243,6 +335,13 @@ static const struct of_device_id realtek_gpio_of_match[] = {  	{  		.compatible = "realtek,rtl8390-gpio",  	}, +	{ +		.compatible = "realtek,rtl9300-gpio", +		.data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU) +	}, +	{ +		.compatible = "realtek,rtl9310-gpio", +	},  	{}  };  MODULE_DEVICE_TABLE(of, realtek_gpio_of_match); @@ -250,11 +349,14 @@ MODULE_DEVICE_TABLE(of, realtek_gpio_of_match);  static int realtek_gpio_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; +	unsigned long bgpio_flags;  	unsigned int dev_flags;  	struct gpio_irq_chip *girq;  	struct realtek_gpio_ctrl *ctrl; +	struct resource *res;  	u32 ngpios; -	int err, irq; +	unsigned int nr_cpus; +	int cpu, err, irq;  	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);  	if (!ctrl) @@ -277,10 +379,20 @@ static int realtek_gpio_probe(struct platform_device *pdev)  	raw_spin_lock_init(&ctrl->lock); +	if (dev_flags & GPIO_PORTS_REVERSED) { +		bgpio_flags = 0; +		ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev; +		ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev; +	} else { +		bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; +		ctrl->port_offset_u8 = realtek_gpio_port_offset_u8; +		ctrl->port_offset_u16 = realtek_gpio_port_offset_u16; +	} +  	err = bgpio_init(&ctrl->gc, dev, 4,  		ctrl->base + REALTEK_GPIO_REG_DATA, NULL, NULL,  		ctrl->base + REALTEK_GPIO_REG_DIR, NULL, -		BGPIOF_BIG_ENDIAN_BYTE_ORDER); +		bgpio_flags);  	if (err) {  		dev_err(dev, "unable to init generic GPIO");  		return err; @@ -305,6 +417,21 @@ static int realtek_gpio_probe(struct platform_device *pdev)  		girq->init_hw = realtek_gpio_irq_init;  	} +	cpumask_clear(&ctrl->cpu_irq_maskable); + +	if ((dev_flags & GPIO_INTERRUPTS_PER_CPU) && irq > 0) { +		ctrl->cpumask_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); +		if (IS_ERR(ctrl->cpumask_base)) +			return dev_err_probe(dev, PTR_ERR(ctrl->cpumask_base), +				"missing CPU IRQ mask registers"); + +		nr_cpus = resource_size(res) / REALTEK_GPIO_PORTS_PER_BANK; +		nr_cpus = min(nr_cpus, num_present_cpus()); + +		for (cpu = 0; cpu < nr_cpus; cpu++) +			cpumask_set_cpu(cpu, &ctrl->cpu_irq_maskable); +	} +  	return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);  } diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index 099e358d2491..e342a6dc4c6c 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -19,6 +19,7 @@  #include <linux/of_address.h>  #include <linux/of_device.h>  #include <linux/of_irq.h> +#include <linux/pinctrl/pinconf-generic.h>  #include <linux/regmap.h>  #include "../pinctrl/core.h" @@ -706,7 +707,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev)  	struct device_node *pctlnp = of_get_parent(np);  	struct pinctrl_dev *pctldev = NULL;  	struct rockchip_pin_bank *bank = NULL; -	struct rockchip_pin_output_deferred *cfg; +	struct rockchip_pin_deferred *cfg;  	static int gpio;  	int id, ret; @@ -747,15 +748,27 @@ static int rockchip_gpio_probe(struct platform_device *pdev)  		return ret;  	} -	while (!list_empty(&bank->deferred_output)) { -		cfg = list_first_entry(&bank->deferred_output, -				       struct rockchip_pin_output_deferred, head); +	while (!list_empty(&bank->deferred_pins)) { +		cfg = list_first_entry(&bank->deferred_pins, +				       struct rockchip_pin_deferred, head);  		list_del(&cfg->head); -		ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); -		if (ret) -			dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, cfg->arg); - +		switch (cfg->param) { +		case PIN_CONFIG_OUTPUT: +			ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); +			if (ret) +				dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, +					 cfg->arg); +			break; +		case PIN_CONFIG_INPUT_ENABLE: +			ret = rockchip_gpio_direction_input(&bank->gpio_chip, cfg->pin); +			if (ret) +				dev_warn(dev, "setting input pin %u failed\n", cfg->pin); +			break; +		default: +			dev_warn(dev, "unknown deferred config param %d\n", cfg->param); +			break; +		}  		kfree(cfg);  	} diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c index 7d82388b4ab7..238f3210970c 100644 --- a/drivers/gpio/gpio-sifive.c +++ b/drivers/gpio/gpio-sifive.c @@ -44,7 +44,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)  	unsigned long flags;  	unsigned int trigger; -	spin_lock_irqsave(&chip->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&chip->gc.bgpio_lock, flags);  	trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;  	regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),  			   (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0); @@ -54,7 +54,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)  			   (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);  	regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),  			   (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0); -	spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);  }  static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger) @@ -75,22 +75,24 @@ static void sifive_gpio_irq_enable(struct irq_data *d)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);  	struct sifive_gpio *chip = gpiochip_get_data(gc); -	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX; +	irq_hw_number_t hwirq = irqd_to_hwirq(d); +	int offset = hwirq % SIFIVE_GPIO_MAX;  	u32 bit = BIT(offset);  	unsigned long flags; +	gpiochip_enable_irq(gc, hwirq);  	irq_chip_enable_parent(d);  	/* Switch to input */  	gc->direction_input(gc, offset); -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	/* Clear any sticky pending interrupts */  	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);  	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);  	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);  	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	/* Enable interrupts */  	assign_bit(offset, &chip->irq_state, 1); @@ -101,11 +103,13 @@ static void sifive_gpio_irq_disable(struct irq_data *d)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);  	struct sifive_gpio *chip = gpiochip_get_data(gc); -	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX; +	irq_hw_number_t hwirq = irqd_to_hwirq(d); +	int offset = hwirq % SIFIVE_GPIO_MAX;  	assign_bit(offset, &chip->irq_state, 0);  	sifive_gpio_set_ie(chip, offset);  	irq_chip_disable_parent(d); +	gpiochip_disable_irq(gc, hwirq);  }  static void sifive_gpio_irq_eoi(struct irq_data *d) @@ -116,13 +120,13 @@ static void sifive_gpio_irq_eoi(struct irq_data *d)  	u32 bit = BIT(offset);  	unsigned long flags; -	spin_lock_irqsave(&gc->bgpio_lock, flags); +	raw_spin_lock_irqsave(&gc->bgpio_lock, flags);  	/* Clear all pending interrupts */  	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);  	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);  	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);  	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit); -	spin_unlock_irqrestore(&gc->bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);  	irq_chip_eoi_parent(d);  } @@ -137,7 +141,7 @@ static int sifive_gpio_irq_set_affinity(struct irq_data *data,  	return -EINVAL;  } -static struct irq_chip sifive_gpio_irqchip = { +static const struct irq_chip sifive_gpio_irqchip = {  	.name		= "sifive-gpio",  	.irq_set_type	= sifive_gpio_irq_set_type,  	.irq_mask	= irq_chip_mask_parent, @@ -146,6 +150,8 @@ static struct irq_chip sifive_gpio_irqchip = {  	.irq_disable	= sifive_gpio_irq_disable,  	.irq_eoi	= sifive_gpio_irq_eoi,  	.irq_set_affinity = sifive_gpio_irq_set_affinity, +	.flags		= IRQCHIP_IMMUTABLE, +	GPIOCHIP_IRQ_RESOURCE_HELPERS,  };  static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc, @@ -242,7 +248,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)  	chip->gc.parent = dev;  	chip->gc.owner = THIS_MODULE;  	girq = &chip->gc.irq; -	girq->chip = &sifive_gpio_irqchip; +	gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip);  	girq->fwnode = of_node_to_fwnode(node);  	girq->parent_domain = parent;  	girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq; diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 41c31b10ae84..98109839102f 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -314,8 +314,8 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)  	for (i = 0; i < num_lines; i++) {  		attr_group = devm_kzalloc(dev, sizeof(*attr_group), GFP_KERNEL); -		attrs = devm_kcalloc(dev, sizeof(*attrs), -				     GPIO_SIM_NUM_ATTRS, GFP_KERNEL); +		attrs = devm_kcalloc(dev, GPIO_SIM_NUM_ATTRS, sizeof(*attrs), +				     GFP_KERNEL);  		val_attr = devm_kzalloc(dev, sizeof(*val_attr), GFP_KERNEL);  		pull_attr = devm_kzalloc(dev, sizeof(*pull_attr), GFP_KERNEL);  		if (!attr_group || !attrs || !val_attr || !pull_attr) diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index fdd3d497b535..6076937b18e7 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c @@ -38,7 +38,6 @@   */  struct syscon_gpio_data { -	const char	*compatible;  	unsigned int	flags;  	unsigned int	bit_count;  	unsigned int	dat_bit_offset; @@ -125,7 +124,6 @@ static int syscon_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int val)  static const struct syscon_gpio_data clps711x_mctrl_gpio = {  	/* ARM CLPS711X SYSFLG1 Bits 8-10 */ -	.compatible	= "cirrus,ep7209-syscon1",  	.flags		= GPIO_SYSCON_FEAT_IN,  	.bit_count	= 3,  	.dat_bit_offset	= 0x40 * 8 + 8, @@ -182,7 +180,6 @@ static void keystone_gpio_set(struct gpio_chip *chip, unsigned offset, int val)  static const struct syscon_gpio_data keystone_dsp_gpio = {  	/* ARM Keystone 2 */ -	.compatible	= NULL,  	.flags		= GPIO_SYSCON_FEAT_OUT,  	.bit_count	= 28,  	.dat_bit_offset	= 4, @@ -219,33 +216,25 @@ static int syscon_gpio_probe(struct platform_device *pdev)  	priv->data = of_device_get_match_data(dev); -	if (priv->data->compatible) { -		priv->syscon = syscon_regmap_lookup_by_compatible( -					priv->data->compatible); -		if (IS_ERR(priv->syscon)) -			return PTR_ERR(priv->syscon); -	} else { -		priv->syscon = -			syscon_regmap_lookup_by_phandle(np, "gpio,syscon-dev"); -		if (IS_ERR(priv->syscon) && np->parent) -			priv->syscon = syscon_node_to_regmap(np->parent); -		if (IS_ERR(priv->syscon)) -			return PTR_ERR(priv->syscon); +	priv->syscon = syscon_regmap_lookup_by_phandle(np, "gpio,syscon-dev"); +	if (IS_ERR(priv->syscon) && np->parent) +		priv->syscon = syscon_node_to_regmap(np->parent); +	if (IS_ERR(priv->syscon)) +		return PTR_ERR(priv->syscon); -		ret = of_property_read_u32_index(np, "gpio,syscon-dev", 1, -						 &priv->dreg_offset); -		if (ret) -			dev_err(dev, "can't read the data register offset!\n"); +	ret = of_property_read_u32_index(np, "gpio,syscon-dev", 1, +					 &priv->dreg_offset); +	if (ret) +		dev_err(dev, "can't read the data register offset!\n"); -		priv->dreg_offset <<= 3; +	priv->dreg_offset <<= 3; -		ret = of_property_read_u32_index(np, "gpio,syscon-dev", 2, -						 &priv->dir_reg_offset); -		if (ret) -			dev_dbg(dev, "can't read the dir register offset!\n"); +	ret = of_property_read_u32_index(np, "gpio,syscon-dev", 2, +					 &priv->dir_reg_offset); +	if (ret) +		dev_dbg(dev, "can't read the dir register offset!\n"); -		priv->dir_reg_offset <<= 3; -	} +	priv->dir_reg_offset <<= 3;  	priv->chip.parent = dev;  	priv->chip.owner = THIS_MODULE; diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c index 718a508d3b2f..de6afa3f9716 100644 --- a/drivers/gpio/gpio-tb10x.c +++ b/drivers/gpio/gpio-tb10x.c @@ -62,14 +62,14 @@ static inline void tb10x_set_bits(struct tb10x_gpio *gpio, unsigned int offs,  	u32 r;  	unsigned long flags; -	spin_lock_irqsave(&gpio->gc.bgpio_lock, flags); +	raw_spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);  	r = tb10x_reg_read(gpio, offs);  	r = (r & ~mask) | (val & mask);  	tb10x_reg_write(gpio, offs, r); -	spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags); +	raw_spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);  }  static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c index bb02a82e22f4..5078631d8014 100644 --- a/drivers/gpio/gpio-ws16c48.c +++ b/drivers/gpio/gpio-ws16c48.c @@ -47,7 +47,7 @@ struct ws16c48_gpio {  	raw_spinlock_t lock;  	unsigned long irq_mask;  	unsigned long flow_mask; -	unsigned base; +	void __iomem *base;  };  static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset) @@ -73,7 +73,7 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)  	ws16c48gpio->io_state[port] |= mask;  	ws16c48gpio->out_state[port] &= ~mask; -	outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); +	iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->base + port);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); @@ -95,7 +95,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,  		ws16c48gpio->out_state[port] |= mask;  	else  		ws16c48gpio->out_state[port] &= ~mask; -	outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); +	iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->base + port);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); @@ -118,7 +118,7 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)  		return -EINVAL;  	} -	port_state = inb(ws16c48gpio->base + port); +	port_state = ioread8(ws16c48gpio->base + port);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); @@ -131,7 +131,7 @@ static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,  	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);  	unsigned long offset;  	unsigned long gpio_mask; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long port_state;  	/* clear bits array to a clean slate */ @@ -139,7 +139,7 @@ static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,  	for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {  		port_addr = ws16c48gpio->base + offset / 8; -		port_state = inb(port_addr) & gpio_mask; +		port_state = ioread8(port_addr) & gpio_mask;  		bitmap_set_value8(bits, port_state, offset);  	} @@ -166,7 +166,7 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)  		ws16c48gpio->out_state[port] |= mask;  	else  		ws16c48gpio->out_state[port] &= ~mask; -	outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); +	iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->base + port);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);  } @@ -178,7 +178,7 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,  	unsigned long offset;  	unsigned long gpio_mask;  	size_t index; -	unsigned int port_addr; +	void __iomem *port_addr;  	unsigned long bitmask;  	unsigned long flags; @@ -195,7 +195,7 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,  		/* update output state data and set device gpio register */  		ws16c48gpio->out_state[index] &= ~gpio_mask;  		ws16c48gpio->out_state[index] |= bitmask; -		outb(ws16c48gpio->out_state[index], port_addr); +		iowrite8(ws16c48gpio->out_state[index], port_addr);  		raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);  	} @@ -219,10 +219,10 @@ static void ws16c48_irq_ack(struct irq_data *data)  	port_state = ws16c48gpio->irq_mask >> (8*port); -	outb(0x80, ws16c48gpio->base + 7); -	outb(port_state & ~mask, ws16c48gpio->base + 8 + port); -	outb(port_state | mask, ws16c48gpio->base + 8 + port); -	outb(0xC0, ws16c48gpio->base + 7); +	iowrite8(0x80, ws16c48gpio->base + 7); +	iowrite8(port_state & ~mask, ws16c48gpio->base + 8 + port); +	iowrite8(port_state | mask, ws16c48gpio->base + 8 + port); +	iowrite8(0xC0, ws16c48gpio->base + 7);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);  } @@ -244,9 +244,9 @@ static void ws16c48_irq_mask(struct irq_data *data)  	ws16c48gpio->irq_mask &= ~mask; -	outb(0x80, ws16c48gpio->base + 7); -	outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); -	outb(0xC0, ws16c48gpio->base + 7); +	iowrite8(0x80, ws16c48gpio->base + 7); +	iowrite8(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); +	iowrite8(0xC0, ws16c48gpio->base + 7);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);  } @@ -268,9 +268,9 @@ static void ws16c48_irq_unmask(struct irq_data *data)  	ws16c48gpio->irq_mask |= mask; -	outb(0x80, ws16c48gpio->base + 7); -	outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); -	outb(0xC0, ws16c48gpio->base + 7); +	iowrite8(0x80, ws16c48gpio->base + 7); +	iowrite8(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); +	iowrite8(0xC0, ws16c48gpio->base + 7);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);  } @@ -304,9 +304,9 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)  		return -EINVAL;  	} -	outb(0x40, ws16c48gpio->base + 7); -	outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); -	outb(0xC0, ws16c48gpio->base + 7); +	iowrite8(0x40, ws16c48gpio->base + 7); +	iowrite8(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); +	iowrite8(0xC0, ws16c48gpio->base + 7);  	raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); @@ -330,20 +330,20 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)  	unsigned long int_id;  	unsigned long gpio; -	int_pending = inb(ws16c48gpio->base + 6) & 0x7; +	int_pending = ioread8(ws16c48gpio->base + 6) & 0x7;  	if (!int_pending)  		return IRQ_NONE;  	/* loop until all pending interrupts are handled */  	do {  		for_each_set_bit(port, &int_pending, 3) { -			int_id = inb(ws16c48gpio->base + 8 + port); +			int_id = ioread8(ws16c48gpio->base + 8 + port);  			for_each_set_bit(gpio, &int_id, 8)  				generic_handle_domain_irq(chip->irq.domain,  							  gpio + 8*port);  		} -		int_pending = inb(ws16c48gpio->base + 6) & 0x7; +		int_pending = ioread8(ws16c48gpio->base + 6) & 0x7;  	} while (int_pending);  	return IRQ_HANDLED; @@ -370,11 +370,11 @@ static int ws16c48_irq_init_hw(struct gpio_chip *gc)  	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(gc);  	/* Disable IRQ by default */ -	outb(0x80, ws16c48gpio->base + 7); -	outb(0, ws16c48gpio->base + 8); -	outb(0, ws16c48gpio->base + 9); -	outb(0, ws16c48gpio->base + 10); -	outb(0xC0, ws16c48gpio->base + 7); +	iowrite8(0x80, ws16c48gpio->base + 7); +	iowrite8(0, ws16c48gpio->base + 8); +	iowrite8(0, ws16c48gpio->base + 9); +	iowrite8(0, ws16c48gpio->base + 10); +	iowrite8(0xC0, ws16c48gpio->base + 7);  	return 0;  } @@ -396,6 +396,10 @@ static int ws16c48_probe(struct device *dev, unsigned int id)  		return -EBUSY;  	} +	ws16c48gpio->base = devm_ioport_map(dev, base[id], WS16C48_EXTENT); +	if (!ws16c48gpio->base) +		return -ENOMEM; +  	ws16c48gpio->chip.label = name;  	ws16c48gpio->chip.parent = dev;  	ws16c48gpio->chip.owner = THIS_MODULE; @@ -409,7 +413,6 @@ static int ws16c48_probe(struct device *dev, unsigned int id)  	ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple;  	ws16c48gpio->chip.set = ws16c48_gpio_set;  	ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; -	ws16c48gpio->base = base[id];  	girq = &ws16c48gpio->chip.irq;  	girq->chip = &ws16c48_irqchip; diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index f6f8a541348f..ce9d1282165c 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -11,7 +11,6 @@  #include <linux/bitops.h>  #include <linux/io.h>  #include <linux/of_device.h> -#include <linux/of_gpio.h>  #include <linux/slab.h>  #include <linux/gpio/driver.h> @@ -53,22 +52,23 @@  #define ZEVIO_GPIO_BIT(gpio) (gpio&7)  struct zevio_gpio { +	struct gpio_chip        chip;  	spinlock_t		lock; -	struct of_mm_gpio_chip	chip; +	void __iomem		*regs;  };  static inline u32 zevio_gpio_port_get(struct zevio_gpio *c, unsigned pin,  					unsigned port_offset)  {  	unsigned section_offset = ((pin >> 3) & 3)*ZEVIO_GPIO_SECTION_SIZE; -	return readl(IOMEM(c->chip.regs + section_offset + port_offset)); +	return readl(IOMEM(c->regs + section_offset + port_offset));  }  static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin,  					unsigned port_offset, u32 val)  {  	unsigned section_offset = ((pin >> 3) & 3)*ZEVIO_GPIO_SECTION_SIZE; -	writel(val, IOMEM(c->chip.regs + section_offset + port_offset)); +	writel(val, IOMEM(c->regs + section_offset + port_offset));  }  /* Functions for struct gpio_chip */ @@ -178,12 +178,15 @@ static int zevio_gpio_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, controller);  	/* Copy our reference */ -	controller->chip.gc = zevio_gpio_chip; -	controller->chip.gc.parent = &pdev->dev; +	controller->chip = zevio_gpio_chip; +	controller->chip.parent = &pdev->dev; -	status = of_mm_gpiochip_add_data(pdev->dev.of_node, -					 &(controller->chip), -					 controller); +	controller->regs = devm_platform_ioremap_resource(pdev, 0); +	if (IS_ERR(controller->regs)) +		return dev_err_probe(&pdev->dev, PTR_ERR(controller->regs), +				     "failed to ioremap memory resource\n"); + +	status = devm_gpiochip_add_data(&pdev->dev, &controller->chip, controller);  	if (status) {  		dev_err(&pdev->dev, "failed to add gpiochip: %d\n", status);  		return status; @@ -192,10 +195,10 @@ static int zevio_gpio_probe(struct platform_device *pdev)  	spin_lock_init(&controller->lock);  	/* Disable interrupts, they only cause errors */ -	for (i = 0; i < controller->chip.gc.ngpio; i += 8) +	for (i = 0; i < controller->chip.ngpio; i += 8)  		zevio_gpio_port_set(controller, i, ZEVIO_GPIO_INT_MASK, 0xFF); -	dev_dbg(controller->chip.gc.parent, "ZEVIO GPIO controller set up!\n"); +	dev_dbg(controller->chip.parent, "ZEVIO GPIO controller set up!\n");  	return 0;  } diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index ffa0256cad5a..c2900b1be69d 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -197,16 +197,15 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,  	void __user *ip = (void __user *)arg;  	struct gpiohandle_data ghd;  	DECLARE_BITMAP(vals, GPIOHANDLES_MAX); -	int i; +	unsigned int i; +	int ret; -	if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { -		/* NOTE: It's ok to read values of output lines. */ -		int ret = gpiod_get_array_value_complex(false, -							true, -							lh->num_descs, -							lh->descs, -							NULL, -							vals); +	switch (cmd) { +	case GPIOHANDLE_GET_LINE_VALUES_IOCTL: +		/* NOTE: It's okay to read values of output lines */ +		ret = gpiod_get_array_value_complex(false, true, +						    lh->num_descs, lh->descs, +						    NULL, vals);  		if (ret)  			return ret; @@ -218,7 +217,7 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,  			return -EFAULT;  		return 0; -	} else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) { +	case GPIOHANDLE_SET_LINE_VALUES_IOCTL:  		/*  		 * All line descriptors were created at once with the same  		 * flags so just check if the first one is really output. @@ -240,10 +239,11 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,  						     lh->descs,  						     NULL,  						     vals); -	} else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) { +	case GPIOHANDLE_SET_CONFIG_IOCTL:  		return linehandle_set_config(lh, ip); +	default: +		return -EINVAL;  	} -	return -EINVAL;  }  #ifdef CONFIG_COMPAT @@ -1188,14 +1188,16 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,  	struct linereq *lr = file->private_data;  	void __user *ip = (void __user *)arg; -	if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL) +	switch (cmd) { +	case GPIO_V2_LINE_GET_VALUES_IOCTL:  		return linereq_get_values(lr, ip); -	else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL) +	case GPIO_V2_LINE_SET_VALUES_IOCTL:  		return linereq_set_values(lr, ip); -	else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL) +	case GPIO_V2_LINE_SET_CONFIG_IOCTL:  		return linereq_set_config(lr, ip); - -	return -EINVAL; +	default: +		return -EINVAL; +	}  }  #ifdef CONFIG_COMPAT @@ -2113,28 +2115,30 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  		return -ENODEV;  	/* Fill in the struct and pass to userspace */ -	if (cmd == GPIO_GET_CHIPINFO_IOCTL) { +	switch (cmd) { +	case GPIO_GET_CHIPINFO_IOCTL:  		return chipinfo_get(cdev, ip);  #ifdef CONFIG_GPIO_CDEV_V1 -	} else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { +	case GPIO_GET_LINEHANDLE_IOCTL:  		return linehandle_create(gdev, ip); -	} else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { +	case GPIO_GET_LINEEVENT_IOCTL:  		return lineevent_create(gdev, ip); -	} else if (cmd == GPIO_GET_LINEINFO_IOCTL || -		   cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { -		return lineinfo_get_v1(cdev, ip, -				       cmd == GPIO_GET_LINEINFO_WATCH_IOCTL); +	case GPIO_GET_LINEINFO_IOCTL: +		return lineinfo_get_v1(cdev, ip, false); +	case GPIO_GET_LINEINFO_WATCH_IOCTL: +		return lineinfo_get_v1(cdev, ip, true);  #endif /* CONFIG_GPIO_CDEV_V1 */ -	} else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL || -		   cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) { -		return lineinfo_get(cdev, ip, -				    cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL); -	} else if (cmd == GPIO_V2_GET_LINE_IOCTL) { +	case GPIO_V2_GET_LINEINFO_IOCTL: +		return lineinfo_get(cdev, ip, false); +	case GPIO_V2_GET_LINEINFO_WATCH_IOCTL: +		return lineinfo_get(cdev, ip, true); +	case GPIO_V2_GET_LINE_IOCTL:  		return linereq_create(gdev, ip); -	} else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { +	case GPIO_GET_LINEINFO_UNWATCH_IOCTL:  		return lineinfo_unwatch(cdev, ip); +	default: +		return -EINVAL;  	} -	return -EINVAL;  }  #ifdef CONFIG_COMPAT diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 7e5e51d49d09..3d6c3ffd5576 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -712,9 +712,8 @@ static void of_gpiochip_remove_hog(struct gpio_chip *chip,  				   struct device_node *hog)  {  	struct gpio_desc *desc; -	unsigned int i; -	for_each_gpio_desc_with_flag(i, chip, desc, FLAG_IS_HOGGED) +	for_each_gpio_desc_with_flag(chip, desc, FLAG_IS_HOGGED)  		if (desc->hog == hog)  			gpiochip_free_own_desc(desc);  } @@ -931,6 +930,11 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)  	if (!np)  		return 0; +	if (!of_property_read_bool(np, "gpio-ranges") && +	    chip->of_gpio_ranges_fallback) { +		return chip->of_gpio_ranges_fallback(chip, np); +	} +  	group_names = of_find_property(np, group_names_propname, NULL);  	for (;; index++) { diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index d44ffea038f5..cd27bf173dec 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -760,7 +760,6 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)  {  	struct gpio_desc *desc;  	struct gpio_chip *chip = gdev->chip; -	unsigned int i;  	if (!gdev->mockdev)  		return; @@ -773,7 +772,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)  	mutex_unlock(&sysfs_lock);  	/* unregister gpiod class devices owned by sysfs */ -	for_each_gpio_desc_with_flag(i, chip, desc, FLAG_SYSFS) +	for_each_gpio_desc_with_flag(chip, desc, FLAG_SYSFS)  		gpiod_free(desc);  } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 690035124faa..9fff4f464ca3 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -189,9 +189,8 @@ static int gpiochip_find_base(int ngpio)  		/* found a free space? */  		if (gdev->base + gdev->ngpio <= base)  			break; -		else -			/* nope, check the space right before the chip */ -			base = gdev->base - ngpio; +		/* nope, check the space right before the chip */ +		base = gdev->base - ngpio;  	}  	if (gpio_is_valid(base)) { @@ -289,7 +288,6 @@ static int gpiodev_add_to_list(struct gpio_device *gdev)  		}  	} -	dev_err(&gdev->dev, "GPIO integer space overlap, cannot add chip\n");  	return -EBUSY;  } @@ -310,15 +308,10 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)  	spin_lock_irqsave(&gpio_lock, flags);  	list_for_each_entry(gdev, &gpio_devices, list) { -		int i; +		struct gpio_desc *desc; -		for (i = 0; i != gdev->ngpio; ++i) { -			struct gpio_desc *desc = &gdev->descs[i]; - -			if (!desc->name) -				continue; - -			if (!strcmp(desc->name, name)) { +		for_each_gpio_desc(gdev->chip, desc) { +			if (desc->name && !strcmp(desc->name, name)) {  				spin_unlock_irqrestore(&gpio_lock, flags);  				return desc;  			} @@ -728,6 +721,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,  	ret = gpiodev_add_to_list(gdev);  	if (ret) {  		spin_unlock_irqrestore(&gpio_lock, flags); +		chip_err(gc, "GPIO integer space overlap, cannot add chip\n");  		goto err_free_label;  	} @@ -2427,8 +2421,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)  			ret = gpiod_direction_input(desc);  			goto set_output_flag;  		} -	} -	else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) { +	} else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {  		ret = gpio_set_config(desc, PIN_CONFIG_DRIVE_OPEN_SOURCE);  		if (!ret)  			goto set_output_value; @@ -2546,6 +2539,11 @@ void gpiod_toggle_active_low(struct gpio_desc *desc)  }  EXPORT_SYMBOL_GPL(gpiod_toggle_active_low); +static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc) +{ +	return gc->get ? gc->get(gc, gpio_chip_hwgpio(desc)) : -EIO; +} +  /* I/O calls are only valid after configuration completed; the relevant   * "is this a valid GPIO" error checks should already have been done.   * @@ -2571,12 +2569,10 @@ EXPORT_SYMBOL_GPL(gpiod_toggle_active_low);  static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)  {  	struct gpio_chip	*gc; -	int offset;  	int value;  	gc = desc->gdev->chip; -	offset = gpio_chip_hwgpio(desc); -	value = gc->get ? gc->get(gc, offset) : -EIO; +	value = gpio_chip_get_value(gc, desc);  	value = value < 0 ? value : !!value;  	trace_gpio_value(desc_to_gpio(desc), 1, value);  	return value; @@ -2585,9 +2581,9 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)  static int gpio_chip_get_multiple(struct gpio_chip *gc,  				  unsigned long *mask, unsigned long *bits)  { -	if (gc->get_multiple) { +	if (gc->get_multiple)  		return gc->get_multiple(gc, mask, bits); -	} else if (gc->get) { +	if (gc->get) {  		int i, value;  		for_each_set_bit(i, mask, gc->ngpio) { @@ -4147,9 +4143,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,  static void gpiochip_free_hogs(struct gpio_chip *gc)  {  	struct gpio_desc *desc; -	int id; -	for_each_gpio_desc_with_flag(id, gc, desc, FLAG_IS_HOGGED) +	for_each_gpio_desc_with_flag(gc, desc, FLAG_IS_HOGGED)  		gpiochip_free_own_desc(desc);  } @@ -4409,34 +4404,32 @@ core_initcall(gpiolib_dev_init);  static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)  { -	unsigned		i;  	struct gpio_chip	*gc = gdev->chip; +	struct gpio_desc	*desc;  	unsigned		gpio = gdev->base; -	struct gpio_desc	*gdesc = &gdev->descs[0]; +	int			value;  	bool			is_out;  	bool			is_irq;  	bool			active_low; -	for (i = 0; i < gdev->ngpio; i++, gpio++, gdesc++) { -		if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) { -			if (gdesc->name) { -				seq_printf(s, " gpio-%-3d (%-20.20s)\n", -					   gpio, gdesc->name); -			} -			continue; +	for_each_gpio_desc(gc, desc) { +		if (test_bit(FLAG_REQUESTED, &desc->flags)) { +			gpiod_get_direction(desc); +			is_out = test_bit(FLAG_IS_OUT, &desc->flags); +			value = gpio_chip_get_value(gc, desc); +			is_irq = test_bit(FLAG_USED_AS_IRQ, &desc->flags); +			active_low = test_bit(FLAG_ACTIVE_LOW, &desc->flags); +			seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s\n", +				   gpio, desc->name ?: "", desc->label, +				   is_out ? "out" : "in ", +				   value >= 0 ? (value ? "hi" : "lo") : "?  ", +				   is_irq ? "IRQ " : "", +				   active_low ? "ACTIVE LOW" : ""); +		} else if (desc->name) { +			seq_printf(s, " gpio-%-3d (%-20.20s)\n", gpio, desc->name);  		} -		gpiod_get_direction(gdesc); -		is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); -		is_irq = test_bit(FLAG_USED_AS_IRQ, &gdesc->flags); -		active_low = test_bit(FLAG_ACTIVE_LOW, &gdesc->flags); -		seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s", -			gpio, gdesc->name ? gdesc->name : "", gdesc->label, -			is_out ? "out" : "in ", -			gc->get ? (gc->get(gc, i) ? "hi" : "lo") : "?  ", -			is_irq ? "IRQ " : "", -			active_low ? "ACTIVE LOW" : ""); -		seq_printf(s, "\n"); +		gpio++;  	}  } diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 06f3faa9fbef..eef3ec073d9e 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -100,10 +100,13 @@ struct gpio_array {  struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, unsigned int hwnum); -#define for_each_gpio_desc_with_flag(i, gc, desc, flag)		\ -	for (i = 0, desc = gpiochip_get_desc(gc, i);		\ -	     i < gc->ngpio;					\ -	     i++, desc = gpiochip_get_desc(gc, i))		\ +#define for_each_gpio_desc(gc, desc)					\ +	for (unsigned int __i = 0;					\ +	     __i < gc->ngpio && (desc = gpiochip_get_desc(gc, __i));	\ +	     __i++)							\ + +#define for_each_gpio_desc_with_flag(gc, desc, flag)			\ +	for_each_gpio_desc(gc, desc)					\  		if (!test_bit(flag, &desc->flags)) {} else  int gpiod_get_array_value_complex(bool raw, bool can_sleep,  | 
