mirror of https://gitee.com/openkylin/linux.git
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:
commit
bc909421a9
|
@ -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;
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue