diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-30 15:56:22 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-30 15:56:22 -0700 | 
| commit | bc909421a9c7083fcde795846d22b36a51a7be54 (patch) | |
| tree | 64c9b5e68b1c0fa5a40ba5f65dbfcf18b2c8b40e | |
| parent | 8c673cbc7682b3f2862fe42f8069cac20c09e160 (diff) | |
| parent | 8fcff5f13773aa3898df1d13a1615d468079cb15 (diff) | |
| download | olio-linux-3.10-bc909421a9c7083fcde795846d22b36a51a7be54.tar.xz olio-linux-3.10-bc909421a9c7083fcde795846d22b36a51a7be54.zip  | |
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
| -rw-r--r-- | drivers/gpio/gpio-74x164.c | 2 | ||||
| -rw-r--r-- | drivers/gpio/gpio-mvebu.c | 4 | ||||
| -rw-r--r-- | drivers/gpio/gpio-omap.c | 35 | ||||
| -rw-r--r-- | drivers/gpio/gpio-timberdale.c | 4 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib.c | 10 | 
5 files changed, 48 insertions, 7 deletions
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index ed3e55161bd..f05e54258ff 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -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; diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 7a874129e5d..cf7afb9eb61 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -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. */ diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 94cbc842fbc..d335af1d4d8 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -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 */ diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index 031c6adf5b6..1a3e2b9b477 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -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);  } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5d6c71edc73..1c8d9e3380e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -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)  |