diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-10-20 12:15:30 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-10-20 12:15:30 -0400 |
commit | 107532920226a37e595697959b2a6a823cfa2497 (patch) | |
tree | 7d35c84ed324e6cabeed29282f1fc97994fd204b /drivers/gpio | |
parent | 29ea35969b92a4be122a58c4aceea8c5e2c388d9 (diff) | |
parent | ecb7b0e33e048e63d1169e6fee277430c70ddf0b (diff) |
Merge branch 'tegra/devel' into next/devel
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-tegra.c | 143 |
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 | ||
78 | static struct tegra_gpio_bank tegra_gpio_banks[] = { | 77 | static void __iomem *regs; |
79 | {.bank = 0, .irq = INT_GPIO1}, | 78 | static struct tegra_gpio_bank tegra_gpio_banks[7]; |
80 | {.bank = 1, .irq = INT_GPIO2}, | 79 | |
81 | {.bank = 2, .irq = INT_GPIO3}, | 80 | static 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 | }; | 85 | static inline u32 tegra_gpio_readl(u32 reg) |
86 | { | ||
87 | return __raw_readl(regs + reg); | ||
88 | } | ||
87 | 89 | ||
88 | static int tegra_gpio_compose(int bank, int port, int bit) | 90 | static 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 | ||
103 | void tegra_gpio_enable(int gpio) | 105 | void tegra_gpio_enable(int gpio) |
@@ -117,7 +119,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
117 | 119 | ||
118 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) | 120 | static 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 | ||
123 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 125 | static 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 | ||
156 | static void tegra_gpio_irq_mask(struct irq_data *d) | 158 | static 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 | */ |
329 | static struct lock_class_key gpio_lock_class; | 331 | static struct lock_class_key gpio_lock_class; |
330 | 332 | ||
331 | static int __init tegra_gpio_init(void) | 333 | static 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 | ||
407 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
408 | { .compatible = "nvidia,tegra20-gpio", }, | ||
409 | { }, | ||
410 | }; | ||
411 | |||
412 | static 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 | |||
421 | static int __init tegra_gpio_init(void) | ||
422 | { | ||
423 | return platform_driver_register(&tegra_gpio_driver); | ||
424 | } | ||
378 | postcore_initcall(tegra_gpio_init); | 425 | postcore_initcall(tegra_gpio_init); |
379 | 426 | ||
380 | void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) | 427 | void __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; |