Some GPIO fixes for the v3.7 series since -rc1:

- 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 initialized the mask_cach on the mvebu driver
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJQkFIMAAoJEEEQszewGV1zN4YQAKzSPyC4lsdr5sf3Ua0Xxr0l
 7Qb2tbIc9WT9E5m13h0V+sF6XVN+e3Ideg7ZFQOkuqmijA17W1Gm+hRMFYNLvhT9
 ZbVlLdzDMNrKA3VEkP4Eo4KO34awYUBkWE4UglW0PAWz1W222nn9c8HC14tasKke
 i80K55v82l8t7VhfotXhAf1DYhzxpTTzD2CBvGsgpACrNrEXMuKE68ZjeNft/HQU
 CyKmxO5bcmdkF20W2IlQtyAUJridBe5YzUdPQ0PjWi3Ejvpo13i+RHDudiDJfHpv
 5CNddMpXCC5Dl16j5EdEaKLq62mtDYlxzc65NwrRT1SYMsTyluk8faHhzqcACICS
 EoP1mbUWPOkXZxPKLudMqsT0N8ud+XSDfaFIItaP7CMEE/Omf5Ql6Rann0mWxHEP
 m8b913NAwIXtrtBn5/JAk5yqgon2Ns5+b4QxP5nc2Zzge8o9H7I1gLCsh2NFiwV4
 3aABVWUq9EFOiiCvc6K7ZaEH+5/oUrw0qnEEoEUw79Qz/XFlkVvVxcLX9ZOy6Vhd
 3RIgQPnJkNMX1Ncu+Jgd5GMJu1xMsy+urRf+VpaOReKkwiK+s6QTfeSxQBc2g+L5
 n2GR0LvnN9yDFWb9g/NUTSNJ2EjHlWtQPU7KdZRYIxey67FMRdjgA8CSnEFyiI+x
 Wq2Fx2uLE1dv/oYzFbck
 =GXA+
 -----END PGP SIGNATURE-----

Merge tag 'gpio-fixes-v3.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

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
This commit is contained in:
Linus Torvalds 2012-10-30 15:56:22 -07:00
commit bc909421a9
5 changed files with 48 additions and 7 deletions

View File

@ -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->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) { if (!chip->buffer) {
ret = -ENOMEM; ret = -ENOMEM;
goto exit_destroy; goto exit_destroy;

View File

@ -244,6 +244,8 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
if (ret) if (ret)
return ret; return ret;
mvebu_gpio_set(chip, pin, value);
spin_lock_irqsave(&mvchip->lock, flags); spin_lock_irqsave(&mvchip->lock, flags);
u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
u &= ~(1 << pin); u &= ~(1 << pin);
@ -644,7 +646,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
ct->handler = handle_edge_irq; ct->handler = handle_edge_irq;
ct->chip.name = mvchip->chip.label; 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); IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
/* Setup irq domain on top of the generic chip. */ /* Setup irq domain on top of the generic chip. */

View File

@ -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, static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
unsigned trigger) unsigned trigger)
{ {
@ -539,6 +573,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
_set_gpio_irqenable(bank, gpio, 0); _set_gpio_irqenable(bank, gpio, 0);
_clear_gpio_irqstatus(bank, gpio); _clear_gpio_irqstatus(bank, gpio);
_set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); _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 */ /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */

View File

@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tgpio->lock, 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); iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
spin_unlock_irqrestore(&tgpio->lock, flags); spin_unlock_irqrestore(&tgpio->lock, flags);
} }
@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tgpio->lock, 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); iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
spin_unlock_irqrestore(&tgpio->lock, flags); spin_unlock_irqrestore(&tgpio->lock, flags);
} }

View File

@ -623,9 +623,11 @@ static ssize_t export_store(struct class *class,
*/ */
status = gpio_request(gpio, "sysfs"); status = gpio_request(gpio, "sysfs");
if (status < 0) if (status < 0) {
if (status == -EPROBE_DEFER)
status = -ENODEV;
goto done; goto done;
}
status = gpio_export(gpio, true); status = gpio_export(gpio, true);
if (status < 0) if (status < 0)
gpio_free(gpio); gpio_free(gpio);
@ -1191,8 +1193,10 @@ int gpio_request(unsigned gpio, const char *label)
spin_lock_irqsave(&gpio_lock, flags); spin_lock_irqsave(&gpio_lock, flags);
if (!gpio_is_valid(gpio)) if (!gpio_is_valid(gpio)) {
status = -EINVAL;
goto done; goto done;
}
desc = &gpio_desc[gpio]; desc = &gpio_desc[gpio];
chip = desc->chip; chip = desc->chip;
if (chip == NULL) if (chip == NULL)