--- zzzz-none-000/linux-3.10.107/arch/mips/ath79/gpio.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/mips/ath79/gpio.c 2021-02-04 17:41:59.000000000 +0000 @@ -11,133 +11,39 @@ * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. */ - #include -#include #include -#include -#include #include -#include #include - #include #include #include "common.h" -static void __iomem *ath79_gpio_base; -static unsigned long ath79_gpio_count; -static DEFINE_SPINLOCK(ath79_gpio_lock); - -static void __ath79_gpio_set_value(unsigned gpio, int value) -{ - void __iomem *base = ath79_gpio_base; - - if (value) - __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET); - else - __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR); -} - -static int __ath79_gpio_get_value(unsigned gpio) -{ - return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1; -} - -static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - return __ath79_gpio_get_value(offset); -} - -static void ath79_gpio_set_value(struct gpio_chip *chip, - unsigned offset, int value) -{ - __ath79_gpio_set_value(offset, value); -} - -static int ath79_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); - - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), - base + AR71XX_GPIO_REG_OE); - - spin_unlock_irqrestore(&ath79_gpio_lock, flags); - - return 0; -} - -static int ath79_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); - - if (value) - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); - else - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); - - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), - base + AR71XX_GPIO_REG_OE); - - spin_unlock_irqrestore(&ath79_gpio_lock, flags); - - return 0; -} - -static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); - - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), - base + AR71XX_GPIO_REG_OE); - - spin_unlock_irqrestore(&ath79_gpio_lock, flags); - - return 0; -} +void __iomem *ath79_gpio_base; +EXPORT_SYMBOL_GPL(ath79_gpio_base); -static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) +static void __iomem *ath79_gpio_get_function_reg(void) { - void __iomem *base = ath79_gpio_base; - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); + u32 reg = 0; - if (value) - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); + if (soc_is_ar71xx() || + soc_is_ar724x() || + soc_is_ar913x() || + soc_is_ar933x()) + reg = AR71XX_GPIO_REG_FUNC; + else if (soc_is_ar934x() || + soc_is_qca953x() || + soc_is_qca956x() || + soc_is_qcn550x() || + soc_is_tp9343()) + reg = AR934X_GPIO_REG_FUNC; else - __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); - - __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), - base + AR71XX_GPIO_REG_OE); - - spin_unlock_irqrestore(&ath79_gpio_lock, flags); + BUG(); - return 0; + return ath79_gpio_base + reg; } -static struct gpio_chip ath79_gpio_chip = { - .label = "ath79", - .get = ath79_gpio_get_value, - .set = ath79_gpio_set_value, - .direction_input = ath79_gpio_direction_input, - .direction_output = ath79_gpio_direction_output, - .base = 0, -}; - -static void __iomem *ath79_gpio_get_function_reg(void) +static void __iomem *ath79_gpio_get_function2_reg(void) { u32 reg = 0; @@ -145,27 +51,30 @@ soc_is_ar724x() || soc_is_ar913x() || soc_is_ar933x()) - reg = AR71XX_GPIO_REG_FUNC; - else if (soc_is_ar934x()) - reg = AR934X_GPIO_REG_FUNC; + reg = AR71XX_GPIO_REG_FUNC_2; else BUG(); return ath79_gpio_base + reg; } + +void ath79_gpio_function2_setup(u32 set, u32 clear) +{ + void __iomem *reg = ath79_gpio_get_function2_reg(); + + __raw_writel((__raw_readl(reg) & ~clear) | set, reg); + /* flush write */ + __raw_readl(reg); +} + void ath79_gpio_function_setup(u32 set, u32 clear) { void __iomem *reg = ath79_gpio_get_function_reg(); - unsigned long flags; - - spin_lock_irqsave(&ath79_gpio_lock, flags); __raw_writel((__raw_readl(reg) & ~clear) | set, reg); /* flush write */ __raw_readl(reg); - - spin_unlock_irqrestore(&ath79_gpio_lock, flags); } void ath79_gpio_function_enable(u32 mask) @@ -178,67 +87,49 @@ ath79_gpio_function_setup(0, mask); } -void __init ath79_gpio_init(void) +void __init ath79_gpio_output_select(unsigned gpio, u8 val) { - int err; + void __iomem *base = ath79_gpio_base; + unsigned int reg, reg_base; + u32 t, s; - if (soc_is_ar71xx()) - ath79_gpio_count = AR71XX_GPIO_COUNT; - else if (soc_is_ar7240()) - ath79_gpio_count = AR7240_GPIO_COUNT; - else if (soc_is_ar7241() || soc_is_ar7242()) - ath79_gpio_count = AR7241_GPIO_COUNT; - else if (soc_is_ar913x()) - ath79_gpio_count = AR913X_GPIO_COUNT; - else if (soc_is_ar933x()) - ath79_gpio_count = AR933X_GPIO_COUNT; - else if (soc_is_ar934x()) - ath79_gpio_count = AR934X_GPIO_COUNT; + if (soc_is_ar934x()) + reg_base = AR934X_GPIO_REG_OUT_FUNC0; + else if (soc_is_qca953x()) + reg_base = QCA953X_GPIO_REG_OUT_FUNC0; else if (soc_is_qca955x()) - ath79_gpio_count = QCA955X_GPIO_COUNT; + reg_base = QCA955X_GPIO_REG_OUT_FUNC0; + else if (soc_is_qca956x()) + reg_base = QCA956X_GPIO_REG_OUT_FUNC0; + else if (soc_is_qcn550x()) + reg_base = QCN550X_GPIO_REG_OUT_FUNC0; else BUG(); - ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); - ath79_gpio_chip.ngpio = ath79_gpio_count; - if (soc_is_ar934x() || soc_is_qca955x()) { - ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; - ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; - } - - err = gpiochip_add(&ath79_gpio_chip); - if (err) - panic("cannot add AR71xx GPIO chip, error=%d", err); -} + reg = reg_base + 4 * (gpio / 4); + s = 8 * (gpio % 4); -int gpio_get_value(unsigned gpio) -{ - if (gpio < ath79_gpio_count) - return __ath79_gpio_get_value(gpio); + t = __raw_readl(base + reg); + t &= ~(0xff << s); + t |= val << s; + __raw_writel(t, base + reg); - return __gpio_get_value(gpio); + /* flush write */ + (void) __raw_readl(base + reg); } -EXPORT_SYMBOL(gpio_get_value); -void gpio_set_value(unsigned gpio, int value) +int ath79_gpio_direction_select(unsigned gpio, bool oe) { - if (gpio < ath79_gpio_count) - __ath79_gpio_set_value(gpio, value); - else - __gpio_set_value(gpio, value); -} -EXPORT_SYMBOL(gpio_set_value); + void __iomem *base = ath79_gpio_base; + bool ieq_1 = (soc_is_ar934x() || + soc_is_qca953x()); -int gpio_to_irq(unsigned gpio) -{ - /* FIXME */ - return -EINVAL; -} -EXPORT_SYMBOL(gpio_to_irq); + if ((ieq_1 && oe) || (!ieq_1 && !oe)) + __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << gpio), + base + AR71XX_GPIO_REG_OE); + else + __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << gpio), + base + AR71XX_GPIO_REG_OE); -int irq_to_gpio(unsigned irq) -{ - /* FIXME */ - return -EINVAL; + return 0; } -EXPORT_SYMBOL(irq_to_gpio);