Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc909421 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull GPIO fixes from Linus Walleij:
 - Fix a potential bit wrap issue in the Timberdale driver
 - Fix up the buffer allocation size in the 74x164 driver
 - Set the value in direction_output() right in the mvebu driver
 - Return proper error codes for invalid GPIOs
 - Fix an off-mode bug for the OMAP
 - Don't initialize the mask_cach on the mvebu driver

* tag 'gpio-fixes-v3.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  GPIO: mvebu-gpio: Don't initialize the mask_cache
  gpio/omap: fix off-mode bug: clear debounce settings on free/reset
  gpiolib: Don't return -EPROBE_DEFER to sysfs, or for invalid gpios
  gpio: mvebu: correctly set the value in direction_output()
  gpio-74x164: Fix buffer allocation size
  gpio-timberdale: fix a potential wrapping issue
parents 8c673cbc 8fcff5f1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ static int __devinit gen_74x164_probe(struct spi_device *spi)
	}

	chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
	chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL);
	chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL);
	if (!chip->buffer) {
		ret = -ENOMEM;
		goto exit_destroy;
+3 −1
Original line number Diff line number Diff line
@@ -244,6 +244,8 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
	if (ret)
		return ret;

	mvebu_gpio_set(chip, pin, value);

	spin_lock_irqsave(&mvchip->lock, flags);
	u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
	u &= ~(1 << pin);
@@ -644,7 +646,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
	ct->handler = handle_edge_irq;
	ct->chip.name = mvchip->chip.label;

	irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE,
	irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0,
			       IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);

	/* Setup irq domain on top of the generic chip. */
+35 −0
Original line number Diff line number Diff line
@@ -251,6 +251,40 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
	}
}

/**
 * _clear_gpio_debounce - clear debounce settings for a gpio
 * @bank: the gpio bank we're acting upon
 * @gpio: the gpio number on this @gpio
 *
 * If a gpio is using debounce, then clear the debounce enable bit and if
 * this is the only gpio in this bank using debounce, then clear the debounce
 * time too. The debounce clock will also be disabled when calling this function
 * if this is the only gpio in the bank using debounce.
 */
static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio)
{
	u32 gpio_bit = GPIO_BIT(bank, gpio);

	if (!bank->dbck_flag)
		return;

	if (!(bank->dbck_enable_mask & gpio_bit))
		return;

	bank->dbck_enable_mask &= ~gpio_bit;
	bank->context.debounce_en &= ~gpio_bit;
	__raw_writel(bank->context.debounce_en,
		     bank->base + bank->regs->debounce_en);

	if (!bank->dbck_enable_mask) {
		bank->context.debounce = 0;
		__raw_writel(bank->context.debounce, bank->base +
			     bank->regs->debounce);
		clk_disable(bank->dbck);
		bank->dbck_enabled = false;
	}
}

static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
						unsigned trigger)
{
@@ -539,6 +573,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
	_set_gpio_irqenable(bank, gpio, 0);
	_clear_gpio_irqstatus(bank, gpio);
	_set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
	_clear_gpio_debounce(bank, gpio);
}

/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
+2 −2
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d)
	unsigned long flags;

	spin_lock_irqsave(&tgpio->lock, flags);
	tgpio->last_ier &= ~(1 << offset);
	tgpio->last_ier &= ~(1UL << offset);
	iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
	spin_unlock_irqrestore(&tgpio->lock, flags);
}
@@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d)
	unsigned long flags;

	spin_lock_irqsave(&tgpio->lock, flags);
	tgpio->last_ier |= 1 << offset;
	tgpio->last_ier |= 1UL << offset;
	iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
	spin_unlock_irqrestore(&tgpio->lock, flags);
}
+7 −3
Original line number Diff line number Diff line
@@ -623,9 +623,11 @@ static ssize_t export_store(struct class *class,
	 */

	status = gpio_request(gpio, "sysfs");
	if (status < 0)
	if (status < 0) {
		if (status == -EPROBE_DEFER)
			status = -ENODEV;
		goto done;

	}
	status = gpio_export(gpio, true);
	if (status < 0)
		gpio_free(gpio);
@@ -1191,8 +1193,10 @@ int gpio_request(unsigned gpio, const char *label)

	spin_lock_irqsave(&gpio_lock, flags);

	if (!gpio_is_valid(gpio))
	if (!gpio_is_valid(gpio)) {
		status = -EINVAL;
		goto done;
	}
	desc = &gpio_desc[gpio];
	chip = desc->chip;
	if (chip == NULL)