From aa65fa6cf3c3a558e009fb2c934b85974c2733db Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Fri, 5 Aug 2016 13:00:40 +0930 Subject: [PATCH] gpio/aspeed: Write value on switch to output The Barreleye beep LED turned off during boot despite configuring the default-state device tree property to "on". The gpio framework requires the direction_output() callback in struct gpio_chip to set the value as well as the direction. Tested by John on Barreleye and Joel on ast2500evb. Fixes: https://github.com/openbmc/linux/issues/98 Reported-by: John Wang Signed-off-by: Andrew Jeffery Signed-off-by: Joel Stanley --- drivers/gpio/gpio-aspeed.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 152b7d4484d18..87dfcdf6bc6f1 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -113,23 +113,33 @@ static int aspeed_gpio_get(struct gpio_chip *gc, unsigned int offset) & GPIO_BIT(offset)); } -static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, - int val) +static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, int val) { + u32 reg; + void __iomem *addr; struct aspeed_gpio *gpio = to_aspeed_gpio(gc); const struct aspeed_gpio_bank *bank = to_bank(offset); - unsigned long flags; - u32 reg; - spin_lock_irqsave(&gpio->lock, flags); + addr = bank_val_reg(gpio, bank, GPIO_DATA); - reg = ioread32(bank_val_reg(gpio, bank, GPIO_DATA)); + reg = ioread32(addr); if (val) reg |= GPIO_BIT(offset); else reg &= ~GPIO_BIT(offset); - iowrite32(reg, bank_val_reg(gpio, bank, GPIO_DATA)); + iowrite32(reg, addr); +} + +static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, + int val) +{ + struct aspeed_gpio *gpio = to_aspeed_gpio(gc); + unsigned long flags; + + spin_lock_irqsave(&gpio->lock, flags); + + __aspeed_gpio_set(gc, offset, val); spin_unlock_irqrestore(&gpio->lock, flags); } @@ -164,6 +174,8 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc, reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR)); iowrite32(reg | GPIO_BIT(offset), bank_val_reg(gpio, bank, GPIO_DIR)); + __aspeed_gpio_set(gc, offset, val); + spin_unlock_irqrestore(&gpio->lock, flags); return 0;