diff options
Diffstat (limited to 'arch/mips/ath79/gpio.c')
-rw-r--r-- | arch/mips/ath79/gpio.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index a2f8ca630ed6..29054f211832 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c | |||
@@ -1,9 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X GPIO API support | 2 | * Atheros AR71XX/AR724X/AR913X GPIO API support |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
9 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
9 | * by the Free Software Foundation. | 12 | * by the Free Software Foundation. |
@@ -89,6 +92,42 @@ static int ath79_gpio_direction_output(struct gpio_chip *chip, | |||
89 | return 0; | 92 | return 0; |
90 | } | 93 | } |
91 | 94 | ||
95 | static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
96 | { | ||
97 | void __iomem *base = ath79_gpio_base; | ||
98 | unsigned long flags; | ||
99 | |||
100 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
101 | |||
102 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), | ||
103 | base + AR71XX_GPIO_REG_OE); | ||
104 | |||
105 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
111 | int value) | ||
112 | { | ||
113 | void __iomem *base = ath79_gpio_base; | ||
114 | unsigned long flags; | ||
115 | |||
116 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
117 | |||
118 | if (value) | ||
119 | __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); | ||
120 | else | ||
121 | __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); | ||
122 | |||
123 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), | ||
124 | base + AR71XX_GPIO_REG_OE); | ||
125 | |||
126 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
92 | static struct gpio_chip ath79_gpio_chip = { | 131 | static struct gpio_chip ath79_gpio_chip = { |
93 | .label = "ath79", | 132 | .label = "ath79", |
94 | .get = ath79_gpio_get_value, | 133 | .get = ath79_gpio_get_value, |
@@ -155,11 +194,17 @@ void __init ath79_gpio_init(void) | |||
155 | ath79_gpio_count = AR913X_GPIO_COUNT; | 194 | ath79_gpio_count = AR913X_GPIO_COUNT; |
156 | else if (soc_is_ar933x()) | 195 | else if (soc_is_ar933x()) |
157 | ath79_gpio_count = AR933X_GPIO_COUNT; | 196 | ath79_gpio_count = AR933X_GPIO_COUNT; |
197 | else if (soc_is_ar934x()) | ||
198 | ath79_gpio_count = AR934X_GPIO_COUNT; | ||
158 | else | 199 | else |
159 | BUG(); | 200 | BUG(); |
160 | 201 | ||
161 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); | 202 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); |
162 | ath79_gpio_chip.ngpio = ath79_gpio_count; | 203 | ath79_gpio_chip.ngpio = ath79_gpio_count; |
204 | if (soc_is_ar934x()) { | ||
205 | ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; | ||
206 | ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; | ||
207 | } | ||
163 | 208 | ||
164 | err = gpiochip_add(&ath79_gpio_chip); | 209 | err = gpiochip_add(&ath79_gpio_chip); |
165 | if (err) | 210 | if (err) |