aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-10-20 12:15:30 -0400
committerArnd Bergmann <arnd@arndb.de>2011-10-20 12:15:30 -0400
commit107532920226a37e595697959b2a6a823cfa2497 (patch)
tree7d35c84ed324e6cabeed29282f1fc97994fd204b /drivers/gpio
parent29ea35969b92a4be122a58c4aceea8c5e2c388d9 (diff)
parentecb7b0e33e048e63d1169e6fee277430c70ddf0b (diff)
Merge branch 'tegra/devel' into next/devel
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-tegra.c143
1 files changed, 95 insertions, 48 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 747eb40e8afe..75cf91138b69 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -20,10 +20,11 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23
24#include <linux/io.h> 23#include <linux/io.h>
25#include <linux/gpio.h> 24#include <linux/gpio.h>
26#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/platform_device.h>
27#include <linux/module.h>
27 28
28#include <asm/mach/irq.h> 29#include <asm/mach/irq.h>
29 30
@@ -34,9 +35,7 @@
34#define GPIO_PORT(x) (((x) >> 3) & 0x3) 35#define GPIO_PORT(x) (((x) >> 3) & 0x3)
35#define GPIO_BIT(x) ((x) & 0x7) 36#define GPIO_BIT(x) ((x) & 0x7)
36 37
37#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ 38#define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4)
38 GPIO_BANK(x) * 0x80 + \
39 GPIO_PORT(x) * 4)
40 39
41#define GPIO_CNF(x) (GPIO_REG(x) + 0x00) 40#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
42#define GPIO_OE(x) (GPIO_REG(x) + 0x10) 41#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
@@ -75,15 +74,18 @@ struct tegra_gpio_bank {
75}; 74};
76 75
77 76
78static struct tegra_gpio_bank tegra_gpio_banks[] = { 77static void __iomem *regs;
79 {.bank = 0, .irq = INT_GPIO1}, 78static struct tegra_gpio_bank tegra_gpio_banks[7];
80 {.bank = 1, .irq = INT_GPIO2}, 79
81 {.bank = 2, .irq = INT_GPIO3}, 80static inline void tegra_gpio_writel(u32 val, u32 reg)
82 {.bank = 3, .irq = INT_GPIO4}, 81{
83 {.bank = 4, .irq = INT_GPIO5}, 82 __raw_writel(val, regs + reg);
84 {.bank = 5, .irq = INT_GPIO6}, 83}
85 {.bank = 6, .irq = INT_GPIO7}, 84
86}; 85static inline u32 tegra_gpio_readl(u32 reg)
86{
87 return __raw_readl(regs + reg);
88}
87 89
88static int tegra_gpio_compose(int bank, int port, int bit) 90static int tegra_gpio_compose(int bank, int port, int bit)
89{ 91{
@@ -97,7 +99,7 @@ static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
97 val = 0x100 << GPIO_BIT(gpio); 99 val = 0x100 << GPIO_BIT(gpio);
98 if (value) 100 if (value)
99 val |= 1 << GPIO_BIT(gpio); 101 val |= 1 << GPIO_BIT(gpio);
100 __raw_writel(val, reg); 102 tegra_gpio_writel(val, reg);
101} 103}
102 104
103void tegra_gpio_enable(int gpio) 105void tegra_gpio_enable(int gpio)
@@ -117,7 +119,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
117 119
118static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) 120static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
119{ 121{
120 return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; 122 return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
121} 123}
122 124
123static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 125static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -150,7 +152,7 @@ static void tegra_gpio_irq_ack(struct irq_data *d)
150{ 152{
151 int gpio = d->irq - INT_GPIO_BASE; 153 int gpio = d->irq - INT_GPIO_BASE;
152 154
153 __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); 155 tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
154} 156}
155 157
156static void tegra_gpio_irq_mask(struct irq_data *d) 158static void tegra_gpio_irq_mask(struct irq_data *d)
@@ -203,10 +205,10 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
203 205
204 spin_lock_irqsave(&bank->lvl_lock[port], flags); 206 spin_lock_irqsave(&bank->lvl_lock[port], flags);
205 207
206 val = __raw_readl(GPIO_INT_LVL(gpio)); 208 val = tegra_gpio_readl(GPIO_INT_LVL(gpio));
207 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); 209 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
208 val |= lvl_type << GPIO_BIT(gpio); 210 val |= lvl_type << GPIO_BIT(gpio);
209 __raw_writel(val, GPIO_INT_LVL(gpio)); 211 tegra_gpio_writel(val, GPIO_INT_LVL(gpio));
210 212
211 spin_unlock_irqrestore(&bank->lvl_lock[port], flags); 213 spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
212 214
@@ -232,12 +234,12 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
232 234
233 for (port = 0; port < 4; port++) { 235 for (port = 0; port < 4; port++) {
234 int gpio = tegra_gpio_compose(bank->bank, port, 0); 236 int gpio = tegra_gpio_compose(bank->bank, port, 0);
235 unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & 237 unsigned long sta = tegra_gpio_readl(GPIO_INT_STA(gpio)) &
236 __raw_readl(GPIO_INT_ENB(gpio)); 238 tegra_gpio_readl(GPIO_INT_ENB(gpio));
237 u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); 239 u32 lvl = tegra_gpio_readl(GPIO_INT_LVL(gpio));
238 240
239 for_each_set_bit(pin, &sta, 8) { 241 for_each_set_bit(pin, &sta, 8) {
240 __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); 242 tegra_gpio_writel(1 << pin, GPIO_INT_CLR(gpio));
241 243
242 /* if gpio is edge triggered, clear condition 244 /* if gpio is edge triggered, clear condition
243 * before executing the hander so that we don't 245 * before executing the hander so that we don't
@@ -271,11 +273,11 @@ void tegra_gpio_resume(void)
271 273
272 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { 274 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
273 unsigned int gpio = (b<<5) | (p<<3); 275 unsigned int gpio = (b<<5) | (p<<3);
274 __raw_writel(bank->cnf[p], GPIO_CNF(gpio)); 276 tegra_gpio_writel(bank->cnf[p], GPIO_CNF(gpio));
275 __raw_writel(bank->out[p], GPIO_OUT(gpio)); 277 tegra_gpio_writel(bank->out[p], GPIO_OUT(gpio));
276 __raw_writel(bank->oe[p], GPIO_OE(gpio)); 278 tegra_gpio_writel(bank->oe[p], GPIO_OE(gpio));
277 __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); 279 tegra_gpio_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
278 __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); 280 tegra_gpio_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
279 } 281 }
280 } 282 }
281 283
@@ -294,11 +296,11 @@ void tegra_gpio_suspend(void)
294 296
295 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { 297 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
296 unsigned int gpio = (b<<5) | (p<<3); 298 unsigned int gpio = (b<<5) | (p<<3);
297 bank->cnf[p] = __raw_readl(GPIO_CNF(gpio)); 299 bank->cnf[p] = tegra_gpio_readl(GPIO_CNF(gpio));
298 bank->out[p] = __raw_readl(GPIO_OUT(gpio)); 300 bank->out[p] = tegra_gpio_readl(GPIO_OUT(gpio));
299 bank->oe[p] = __raw_readl(GPIO_OE(gpio)); 301 bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio));
300 bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio)); 302 bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio));
301 bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio)); 303 bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio));
302 } 304 }
303 } 305 }
304 local_irq_restore(flags); 306 local_irq_restore(flags);
@@ -328,27 +330,54 @@ static struct irq_chip tegra_gpio_irq_chip = {
328 */ 330 */
329static struct lock_class_key gpio_lock_class; 331static struct lock_class_key gpio_lock_class;
330 332
331static int __init tegra_gpio_init(void) 333static int __devinit tegra_gpio_probe(struct platform_device *pdev)
332{ 334{
335 struct resource *res;
333 struct tegra_gpio_bank *bank; 336 struct tegra_gpio_bank *bank;
334 int i; 337 int i;
335 int j; 338 int j;
336 339
340 for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
341 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
342 if (!res) {
343 dev_err(&pdev->dev, "Missing IRQ resource\n");
344 return -ENODEV;
345 }
346
347 bank = &tegra_gpio_banks[i];
348 bank->bank = i;
349 bank->irq = res->start;
350 }
351
352 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
353 if (!res) {
354 dev_err(&pdev->dev, "Missing MEM resource\n");
355 return -ENODEV;
356 }
357
358 if (!devm_request_mem_region(&pdev->dev, res->start,
359 resource_size(res),
360 dev_name(&pdev->dev))) {
361 dev_err(&pdev->dev, "Couldn't request MEM resource\n");
362 return -ENODEV;
363 }
364
365 regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
366 if (!regs) {
367 dev_err(&pdev->dev, "Couldn't ioremap regs\n");
368 return -ENODEV;
369 }
370
337 for (i = 0; i < 7; i++) { 371 for (i = 0; i < 7; i++) {
338 for (j = 0; j < 4; j++) { 372 for (j = 0; j < 4; j++) {
339 int gpio = tegra_gpio_compose(i, j, 0); 373 int gpio = tegra_gpio_compose(i, j, 0);
340 __raw_writel(0x00, GPIO_INT_ENB(gpio)); 374 tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
341 } 375 }
342 } 376 }
343 377
344#ifdef CONFIG_OF_GPIO 378#ifdef CONFIG_OF_GPIO
345 /* 379 tegra_gpio_chip.of_node = pdev->dev.of_node;
346 * This isn't ideal, but it gets things hooked up until this 380#endif
347 * driver is converted into a platform_device
348 */
349 tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL,
350 "nvidia,tegra20-gpio");
351#endif /* CONFIG_OF_GPIO */
352 381
353 gpiochip_add(&tegra_gpio_chip); 382 gpiochip_add(&tegra_gpio_chip);
354 383
@@ -375,6 +404,24 @@ static int __init tegra_gpio_init(void)
375 return 0; 404 return 0;
376} 405}
377 406
407static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
408 { .compatible = "nvidia,tegra20-gpio", },
409 { },
410};
411
412static struct platform_driver tegra_gpio_driver = {
413 .driver = {
414 .name = "tegra-gpio",
415 .owner = THIS_MODULE,
416 .of_match_table = tegra_gpio_of_match,
417 },
418 .probe = tegra_gpio_probe,
419};
420
421static int __init tegra_gpio_init(void)
422{
423 return platform_driver_register(&tegra_gpio_driver);
424}
378postcore_initcall(tegra_gpio_init); 425postcore_initcall(tegra_gpio_init);
379 426
380void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) 427void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
@@ -407,13 +454,13 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
407 seq_printf(s, 454 seq_printf(s,
408 "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", 455 "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
409 i, j, 456 i, j,
410 __raw_readl(GPIO_CNF(gpio)), 457 tegra_gpio_readl(GPIO_CNF(gpio)),
411 __raw_readl(GPIO_OE(gpio)), 458 tegra_gpio_readl(GPIO_OE(gpio)),
412 __raw_readl(GPIO_OUT(gpio)), 459 tegra_gpio_readl(GPIO_OUT(gpio)),
413 __raw_readl(GPIO_IN(gpio)), 460 tegra_gpio_readl(GPIO_IN(gpio)),
414 __raw_readl(GPIO_INT_STA(gpio)), 461 tegra_gpio_readl(GPIO_INT_STA(gpio)),
415 __raw_readl(GPIO_INT_ENB(gpio)), 462 tegra_gpio_readl(GPIO_INT_ENB(gpio)),
416 __raw_readl(GPIO_INT_LVL(gpio))); 463 tegra_gpio_readl(GPIO_INT_LVL(gpio)));
417 } 464 }
418 } 465 }
419 return 0; 466 return 0;